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-based login with bcrypt hashing | Secure register and login flow |
| 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/
client/
src/
components/
context/
pages/
services/
App.jsx
index.css
main.jsx
.env.example
package.json
server/
src/
config/
middlewares/
modules/
auth/
checks/
monitors/
subscription/
sockets/
utils/
workers/
app.js
server.js
.env.example
package.json
README.md
Base URL (development): http://localhost:5000/api
- POST /auth/register
- POST /auth/login
- 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
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- 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