PulseCheck is a production-style uptime monitoring SaaS that tracks website health, logs response times, and delivers live status updates through WebSockets. The system is designed as a layered backend with clear separation of concerns, Redis-backed controls, and a client dashboard focused on clarity and speed.
- Product Vision
- Feature Highlights
- Realtime Monitoring Flow
- Tech Stack
- Architecture
- Project Structure
- API Surface
- Environment Variables
- Local Setup
- Stripe Subscription Notes
- Operational Notes
- Roadmap
PulseCheck is built for makers who need a clean, reliable visibility layer for their services:
- Monitor uptime and response time with minimal configuration.
- Receive realtime status updates without dashboard refresh.
- Enforce plan limits and interval rules in a clear, auditable way.
| Domain | Capability | Details |
|---|---|---|
| Auth | JWT sessions with Google OAuth support | Email/password + Google sign-in, refresh, logout |
| Plans | FREE and PRO plan rules | Monitor limits and interval enforcement |
| Monitoring | Scheduled uptime checks | Background worker executes due monitors |
| Telemetry | Check logs with response timing | Status history and latency tracking |
| Realtime | Socket.io status updates | Live monitor status changes per user |
| Performance | Redis rate limiting and caching | Throttled auth and cached monitor lists |
| UI | Dashboard with skeleton states | Fast feedback and custom toasts |
flowchart TD
A[User creates monitor] --> B[Monitor stored in MongoDB]
B --> C[Cron worker schedules checks]
C --> D[HTTP request to target]
D --> E[CheckLog stored]
E --> F[Monitor status updated]
F --> G[Socket.io event emitted]
G --> H[Dashboard updates in realtime]
- React
- Vite
- React Router
- Axios
- socket.io-client
- Node.js + Express
- MongoDB + Mongoose
- Redis + ioredis
- JWT + bcrypt
- node-cron
- Socket.io
- Controllers: HTTP request and response shaping
- Services: business rules, plan enforcement, cache invalidation
- Repositories: MongoDB data access
- Models: schema and persistence
- Workers: interval-driven uptime checks and status updates
- User rooms are established on socket connection
- Status changes emit targeted events to the owning user room
- The client listens and patches the local state for instant UI feedback
PulseCheck/
├── assets/ # Static assets (icons, images, banners, etc.)
├── client/ # Frontend application
└── server/
└── src/
├── config/ # App configuration files
│ ├── db.js # Database connection setup
│ └── redis.js # Redis client configuration
│
├── middlewares/ # Express middlewares
│ ├── auth.middleware.js # Authentication & authorization middleware
│ ├── error.middleware.js # Global error handling middleware
│ ├── rateLimit.middleware.js # API rate limiting
│ └── request.middleware.js # Request validation/logging middleware
│
├── modules/ # Feature-based modules
│ ├── alerts/ # Alert management system
│ ├── analytics/ # Analytics & reporting
│ ├── auth/ # Authentication module
│ ├── checks/ # Health/status check logic
│ ├── incidents/ # Incident tracking & management
│ ├── monitors/ # Monitoring services & uptime checks
│ └── subscription/ # Subscription & billing module
│
├── sockets/
│ └── socket.js # WebSocket / Socket.IO configuration
│
├── utils/ # Utility/helper functions
│ ├── ApiError.js # Custom API error class
│ ├── asyncHandler.js # Async error wrapper
│ ├── constants.js # Application constants
│ └── logger.js # Logging utility
│
├── workers/
│ └── monitor.worker.js # Background monitoring worker
│
├── app.js # Express app initialization
└── server.js # Server entry point
Base URL (development): http://localhost:5000/api
- POST /auth/register
- POST /auth/login
- POST /auth/google
- POST /auth/refresh
- POST /auth/logout
- GET /auth/me
- GET /monitors
- POST /monitors
- DELETE /monitors/:id
- GET /checks/:monitorId
- POST /subscription/checkout
- POST /subscription/webhook
PORT=5000
MONGO_URI=mongodb://127.0.0.1:27017/pulsecheck
REDIS_URL=redis://127.0.0.1:6379
JWT_SECRET=replace_with_a_secure_secret
JWT_REFRESH_SECRET=replace_with_a_second_secure_secret
GOOGLE_CLIENT_ID=your_google_oauth_client_id
CLIENT_URL=http://localhost:5173
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PRO_PRICE_ID=price_...
STRIPE_WEBHOOK_SECRET=whsec_...
ALLOW_MANUAL_PLAN_UPDATES=falseVITE_API_BASE_URL=http://localhost:5000/api
VITE_SOCKET_URL=http://localhost:5000
VITE_GOOGLE_CLIENT_ID=your_google_oauth_client_id- Node.js 18+
- MongoDB
- Redis
- Stripe account for subscription testing
cd server
npm install
cd ../client
npm installcd server
npm run devcd client
npm run devTypical frontend dev URL: http://localhost:5173
- Checkout endpoint: POST /api/subscription/checkout
- Webhook endpoint: POST /api/subscription/webhook
- Manual plan changes are blocked unless
ALLOW_MANUAL_PLAN_UPDATES=true
Card: 4242 4242 4242 4242
Expiry: Any future date, such as 12/34
CVC: Any 3 digits
ZIP/postal code: Any value
Webhook event types:
- checkout.session.completed
- customer.subscription.updated
- customer.subscription.deleted
- MongoDB and Redis must be running before the backend starts.
- The worker runs every minute and checks only due monitors.
- FREE plan: max 5 monitors, minimum 5 minute interval.
- PRO plan: max 50 monitors, minimum 1 minute interval.
- Sidebar navigation scrolls between dashboard sections without changing the URL.
- Add analytics filters and pagination on long lists
- Expand notification channels beyond dashboard updates
- Add tests for service and worker logic