System Architecture
Core Features
Data Management
Frontend Components
Extensibility
The following files were used as context for generating this wiki page:
The Risk Management module provides a robust API for organizations to manage their identified risks. It enables users to create, retrieve, update, and delete risk records, associating them with specific organizations and assignees. The module is designed with a clear separation of concerns, utilizing a controller for API exposure, a service for business logic, and Data Transfer Objects (DTOs) for data validation and schema definition.
This system supports both API key and session-based authentication, ensuring secure access to risk data for the authenticated organization. It integrates with a database to persist risk information, including details like title, description, category, status, likelihood, impact, and treatment strategies.
The Risk Management module is built using the NestJS framework, following a modular architecture. It consists of a RisksModule that encapsulates the RisksController and RisksService, along with Data Transfer Objects (CreateRiskDto, UpdateRiskDto) for defining the structure of incoming and outgoing data.
The RisksModule imports the AuthModule to leverage authentication mechanisms and provides the RisksService to handle all business logic related to risks. The RisksController exposes the API endpoints, delegating complex operations to the RisksService.
Sources: apps/api/src/risks/risks.module.ts, apps/api/src/risks/risks.controller.ts, apps/api/src/risks/risks.service.ts, apps/api/src/risks/dto/create-risk.dto.ts, apps/api/src/risks/dto/update-risk.dto.ts
The RisksController exposes a RESTful API for managing risks. All endpoints are protected by the HybridAuthGuard and require either an API key or session authentication with an X-Organization-Id header. Swagger documentation is integrated, providing detailed operation summaries, descriptions, parameters, and response schemas.
All API endpoints require authentication. This can be achieved via an X-API-Key header for API key authentication or a combination of session cookies and an X-Organization-Id header for session authentication.
| Method | Path | Operation Summary | Description Risk Management is a crucial module within the system, designed to help organizations identify, assess, and manage risks effectively. It provides a comprehensive set of functionalities to track risks, assign responsibilities, monitor their status, and define treatment strategies. The module supports various risk attributes, including categories, departments, likelihood, impact, and residual risk, facilitating a structured approach to risk management.
Sources: apps/api/src/risks/schemas/risk-operations.ts, apps/api/src/risks/dto/create-risk.dto.ts
The following sequence diagram illustrates the typical flow for creating a new risk through the API.
Sources: apps/api/src/risks/risks.controller.ts, apps/api/src/risks/risks.service.ts
Data Transfer Objects (DTOs) are used to define the structure and validation rules for data exchanged between the client and the API.
CreateRiskDtoThis DTO defines the required and optional fields for creating a new risk. It includes validation decorators (@IsString, @IsNotEmpty, @IsOptional, @IsEnum) to ensure data integrity.
Sources: apps/api/src/risks/dto/create-risk.dto.ts
UpdateRiskDtoThe UpdateRiskDto extends PartialType(CreateRiskDto). This means all fields inherited from CreateRiskDto become optional, allowing for partial updates of a risk record.
import { PartialType } from '@nestjs/swagger';
import { CreateRiskDto } from './create-risk.dto';
export class UpdateRiskDto extends PartialType(CreateRiskDto) {}Sources: apps/api/src/risks/dto/update-risk.dto.ts
RisksService)The RisksService encapsulates the core business logic for managing risks. It interacts directly with the database (db.risk) to perform CRUD operations and includes error handling and logging.
findAllByOrganization(organizationId: string): Retrieves all risks associated with a given organization ID, ordered by creation date. It includes assignee user details.findById(id: string, organizationId: string): Fetches a specific risk by its ID and organization ID. Throws NotFoundException if the risk does not exist or does not belong to the specified organization.create(organizationId: string, createRiskDto: CreateRiskDto): Creates a new risk record in the database, associating it with the provided organization ID.updateById(id: string, organizationId: string, updateRiskDto: UpdateRiskDto): Updates an existing risk. It first verifies the risk's existence and ownership using findById before performing the update.deleteById(id: string, organizationId: string): Deletes a risk. Similar to updateById, it first validates the risk's existence and ownership.The updateById and deleteById methods in RisksService follow a common pattern of first verifying the existence and ownership of a risk before proceeding with the modification or deletion.
Sources: apps/api/src/risks/risks.service.ts
Weak password requirements could lead to unauthorized accesscategory | RiskCategory | Yes | Risk category (e.g., technology, financial) | RiskCategory.technology |
department | Departments? | No | Department responsible for the risk (e.g., it, hr) | Departments.it |
status | RiskStatus? | No | Current status of the risk (e.g., open, closed) | RiskStatus.open |
likelihood | Likelihood? | No | Likelihood of the risk occurring (e.g., possible, unlikely) | Likelihood.possible |
impact | Impact? | No | Impact if the risk materializes (e.g., major, minor) | Impact.major |
residualLikelihood | Likelihood? | No | Residual likelihood after treatment | Likelihood.unlikely |
residualImpact | Impact? | No | Residual impact after treatment | Impact.minor |
treatmentStrategyDescription | string? | No | Description of the treatment strategy | Implement multi-factor authentication |
treatmentStrategy | RiskTreatmentType? | No | Risk treatment strategy (e.g., mitigate, accept) | RiskTreatmentType.mitigate |
assigneeId | string? | No | ID of the user assigned to this risk (e.g., mem_abc123def456) | mem_abc123def456 |