You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**i18n**: i18next + react-i18next (translations via PoEditor)
107
107
108
+
---
109
+
110
+
## Backend Architecture Patterns
111
+
112
+
### Repository Pattern & Separation of Concerns
113
+
114
+
The backend enforces a strict three-layer separation between HTTP handling, business logic, and data access:
115
+
116
+
```
117
+
Request → Controller → Service → Repository → MongoDB (Mongoose)
118
+
```
119
+
120
+
-**Controllers** (`/controllers`) handle HTTP concerns only: parsing request params, calling the appropriate service, and returning a response via the `responseHandler` middleware. They contain no business logic.
121
+
-**Services** (`/service/business`) contain all business logic: deciding whether an incident should be created, whether a notification should fire, what state a monitor is in, etc.
122
+
-**Repositories** (`/repositories`) are the sole layer that talks to MongoDB through Mongoose. They expose clean, reusable query methods (e.g. `findByMonitorId`, `createCheck`) so that services never construct raw DB queries directly.
123
+
124
+
This separation makes each layer independently testable and keeps Mongoose-specific code out of business logic. When adding a new feature, the pattern to follow is: add a repository method for any new DB query, call it from a service, and expose it via a controller route.
125
+
126
+
### Monitoring Flow: From Check to Notification
127
+
128
+
Background monitoring runs on a scheduled queue, not on the HTTP request cycle. The high-level flow for uptime monitoring is:
1.**Pulse** (cron scheduler) enqueues a job into a **BullMQ** queue for each active monitor at its configured interval.
140
+
2. A **BullMQ worker** picks up the job and calls `StatusService`, which performs the actual check (HTTP request, TCP port probe, ping, etc.).
141
+
3. The result is persisted as a `Check` document via the repository layer.
142
+
4.`StatusService` compares the new result against the monitor's previous state. If the monitor transitions from up → down (or down → up), it delegates to `IncidentService` to open or resolve an `Incident` document.
143
+
5. On a state change, `NotificationService` reads the monitor's configured `Notification` documents and dispatches alerts to all enabled channels (email, Discord, Slack, webhooks).
144
+
145
+
### Queue System (BullMQ + Redis)
146
+
147
+
Redis serves two roles: job queue storage for BullMQ and ephemeral caching. BullMQ manages concurrency, retries, and backpressure for monitoring jobs, ensuring checks are processed reliably even under load.
148
+
149
+
- Each monitor type (HTTP, port, ping, infrastructure) maps to its own queue worker so failures in one type don't block others.
150
+
- Job scheduling interval is driven by the `interval` field on the `Monitor` model.
151
+
- Failed jobs are retried with configurable backoff before being moved to a dead-letter state.
152
+
- Redis is also used to cache frequently read data (e.g. aggregated stats) to reduce MongoDB query pressure.
153
+
154
+
When working on anything related to check scheduling, incident lifecycle, or notifications, trace the flow starting from the relevant BullMQ worker rather than from the controller layer.
155
+
156
+
---
157
+
108
158
## Code Conventions
109
159
110
160
### Internationalization
@@ -142,4 +192,4 @@ Key Mongoose models in `/server/src/db/models/`:
0 commit comments