|
| 1 | +# Alert Acknowledgement System Implementation |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document outlines the design decisions, technical details, and complexity analysis for the Alert Acknowledgement System implemented as part of issue #122. |
| 6 | + |
| 7 | +## Problem Statement |
| 8 | + |
| 9 | +Security teams and operators need a mechanism to explicitly mark alerts as reviewed. This is crucial to distinguish between active unreviewed alerts and those that have already been acknowledged and processed by a team member. |
| 10 | + |
| 11 | +## Scope of Implementation |
| 12 | + |
| 13 | +- **Data Layer:** Modified `Alert` model in Prisma. |
| 14 | +- **Application Layer:** Introduced `AlertsModule` and `AcknowledgementsModule` with REST controllers and services. |
| 15 | +- **Audit System:** Integrated with the existing `AuditLog` framework to maintain compliance and traceability. |
| 16 | + |
| 17 | +## Design Decisions |
| 18 | + |
| 19 | +1. **Schema Extension vs. New Table:** |
| 20 | + - **Decision:** Add `acknowledgedAt` and `acknowledgedBy` fields directly to the existing `Alert` model. |
| 21 | + - **Justification:** Since an alert is typically acknowledged only once, a 1-to-1 relationship with a dedicated table would introduce unnecessary joins and database overhead. Adding these nullable fields directly to the `Alert` model keeps the schema lean and queries highly performant. |
| 22 | + |
| 23 | +2. **Atomic Operations (Transactions):** |
| 24 | + - **Decision:** The update to the `Alert` model and the creation of the `AuditLog` entry are executed within a Prisma `$transaction`. |
| 25 | + - **Justification:** This ensures atomicity. If generating the audit log fails, the alert will not be marked as acknowledged. This guarantees data integrity and consistency between state and audit trails. |
| 26 | + |
| 27 | +3. **Modular Architecture:** |
| 28 | + - **Decision:** Created a new `AcknowledgementsModule` encapsulated within an `AlertsModule`. |
| 29 | + - **Justification:** Follows NestJS best practices and the existing monorepo structure outlined in `ARCHITECTURE.md`. It separates the core alert logic from specific lifecycle operations like acknowledgements, making the system easier to test and extend. |
| 30 | + |
| 31 | +## Complexity Analysis |
| 32 | + |
| 33 | +### Time Complexity |
| 34 | + |
| 35 | +- **Database Query (Read):** `O(1)` - Primary key lookup to verify the alert exists. |
| 36 | +- **Database Update + Insert (Transaction):** `O(1)` - Updating a single row by its indexed primary key and inserting a single row into the audit log. |
| 37 | +- **Overall Time Complexity:** `O(1)`. The implementation scales linearly and performance will not degrade as the number of alerts grows, assuming standard B-Tree indexing on the primary keys. |
| 38 | + |
| 39 | +### Space Complexity |
| 40 | + |
| 41 | +- **Application Memory:** `O(1)` - Memory footprint is restricted to processing a single DTO and response payload at a time. No unbounded arrays or loops are introduced. |
| 42 | +- **Database Storage:** `O(1)` per operation - Two lightweight columns added to the `Alert` model (`DateTime` and `String`) and one new row inserted into `AuditLog` per acknowledgement. |
| 43 | + |
| 44 | +## Code Explanations |
| 45 | + |
| 46 | +### `acknowledgements.service.ts` |
| 47 | + |
| 48 | +The core business logic resides here. |
| 49 | + |
| 50 | +1. `acknowledgeAlert` checks if the alert exists. If not, it throws a `NotFoundException`. |
| 51 | +2. It checks if `acknowledgedAt` is already set. If so, it throws a `BadRequestException` to prevent duplicate processing. |
| 52 | +3. A `$transaction` is executed to atomically: |
| 53 | + - Update `acknowledgedAt` to the current timestamp. |
| 54 | + - Update `acknowledgedBy` to the `reviewerId`. |
| 55 | + - Create an `AuditLog` entry with action `ALERT_ACKNOWLEDGED`, associating the actor and the `alertId`. |
| 56 | + |
| 57 | +### `acknowledgements.controller.ts` |
| 58 | + |
| 59 | +Exposes the functionality over HTTP. |
| 60 | + |
| 61 | +- Uses `@Post(':id/acknowledge')` routing. |
| 62 | +- Uses `@HttpCode(HttpStatus.OK)` since it's an RPC-style action over a resource rather than a pure resource creation (201). |
| 63 | +- Extracts the `:id` parameter and the `AcknowledgeAlertDto` from the request body. |
0 commit comments