> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alforse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Risk register

> Track risks and opportunities against any entity, rated by severity and likelihood, and drive each to a resolution.

A risk entry records a concern or opportunity associated with another Alforse entity. It has a **type**, independent 1–5 ratings for **severity** and **likelihood**, an assignee, and a status that moves from `"Open"` to `"Closed"` or `"Accepted"`. The quality module's risk register provides the company-wide view; each source entity also displays its related risks.

Open **Quality → Risks** for the company-wide register. You can also create risks from item, customer, supplier, job, quote-line, and maintenance-dispatch pages.

## What a risk entry holds

Every entry is one `riskRegister` record (validated by `riskRegisterValidator` in `apps/erp/app/modules/quality/quality.models.ts`). The fields you set:

FieldType

<details>
  <summary>**title**required</summary>

  Short name for the risk. The only always-required text field.
</details>

<details>
  <summary>**type**required</summary>

  `Risk` or `Opportunity` — the register tracks both downside and upside. Defaults to `Risk`.
</details>

<details>
  <summary>**severity**required`1–5`</summary>

  How bad the impact would be. An independent rating, shown as colored bars (see below).
</details>

<details>
  <summary>**likelihood**required`1–5`</summary>

  How probable it is. Rated on the same 1–5 scale, independent of severity.
</details>

<details>
  <summary>**status**required</summary>

  Where the entry sits in its lifecycle. Defaults to `"Open"`.
</details>

<details>
  <summary>**source**required</summary>

  The kind of entity this risk is tied to — `Customer`, `General`, `Item`, `Job`, `Quote Line`, `Supplier`, or `Work Center`. Set automatically when you add from an entity page; a standalone risk is `General`.
</details>

<details>
  <summary>**assignee**</summary>

  The person responsible. Defaults to whoever created the entry when left blank; a change fires a notification (see below).
</details>

<details>
  <summary>**description**</summary>

  A one-line summary shown in the list and on the entity card.
</details>

<details>
  <summary>**notes**</summary>

  Rich-text detail, stored as JSON.
</details>

NOTE

**There is no combined risk score.**

Severity and likelihood are stored as two separate 1–5 integers (each constrained to 1 through 5). Alforse never multiplies them into a single number or a risk-matrix cell. The UI shows the two ratings side by side, and that is by design. Don't read the register expecting a computed priority.

## Rating severity and likelihood

Both ratings use the same 1–5 scale, rendered by `RiskRating.tsx` as a row of colored bars — one bar per point, colored by level: 1–2 emerald, 3 yellow, 4 orange, 5 red. On an entity card the severity bars sit behind a warning icon and the likelihood bars behind a dice icon, so you can read both at a glance without a number.

Because the two ratings are independent, a low-likelihood, high-severity risk (a rare but catastrophic failure) and a high-likelihood, low-severity one (a frequent nuisance) both show honestly rather than collapsing to the same middle score. You decide how to weigh them.

## Status lifecycle

Status is a free-set enum (`riskStatus` in `quality.models.ts`). Alforse does not enforce a state machine — any status can move to any other; you set where the entry stands.

<details>
  <summary>**Open**</summary>

  A newly raised risk, not yet worked. The default for a new entry.
</details>

<details>
  <summary>**In Review**</summary>

  Being assessed — someone is deciding whether and how to act on it.
</details>

<details>
  <summary>**Mitigating**</summary>

  A treatment is in progress: you're actively reducing the severity or likelihood.
</details>

<details open>
  <summary>**Closed**</summary>

  Resolved. The risk was mitigated away or no longer applies.
</details>

<details>
  <summary>**Accepted**</summary>

  A deliberate decision to live with the risk as-is rather than treat it. An off-path resolution, distinct from `"Closed"`.
</details>

There is no separate "mitigation action" entity: treatment is tracked by moving the status through `"In Review"` → `"Mitigating"` and recording detail in the notes field, then landing on `"Closed"` (treated) or `"Accepted"` (tolerated).

## Attaching risks to entities

The same register surfaces as a card on the pages of the things it protects. Each entity page mounts the shared card with a fixed `source` and passes the record's id, so the card shows only that entity's risks and new entries inherit the right source. Wired entry points:

* **Items** — parts, materials, tools, consumables, and services, via `ItemRiskRegister.tsx` (`source="Item"`, which also fills the dedicated `itemId` foreign key).
* **Customers** — `CustomerRiskRegister.tsx`, at the customer's Risks tab.
* **Suppliers** — `SupplierRiskRegister.tsx`, at the supplier's Risks tab.
* **Jobs** — `JobRiskRegister.tsx` (`source="Job"`, which also fills the item).
* **Quote lines** — `QuoteLineRiskRegister.tsx` (`source="Quote Line"`).
* **Maintenance dispatches** — the dispatch page mounts the card with `source="Work Center"`, keyed to the dispatch's work center.

The `Work Center` source has no card of its own on the work-center page; its risks appear on maintenance dispatches and in the company-wide list, which joins the work center name through the `riskRegisters` view. A standalone risk created from **Quality → Risks** with no entity gets `source="General"`.

TIP

**The list view and the entity cards read different sources.**

The company-wide list (`getRisks`) reads the `riskRegisters` view, which joins the work center name onto the row. The per-entity cards and the single-record edit page read the base `riskRegister` table directly, filtered by `source` and the entity id. Same data, two read paths.

## Who can do what

Creating a risk requires only that you're an **employee** of the company — the new-risk route gates on `role: "employee"`, not a `quality` create permission, so anyone on the floor can raise one. Editing and deleting are stricter: the edit route requires `quality` **update** and the delete route requires `quality` **delete**, and the database enforces the same split.

When you set or change an assignee, Alforse fires a `RiskAssignment` notification to that person (a background `notify` job). On edit it only notifies when the assignee actually changed, so re-saving an entry doesn't re-ping the same owner.

## Relation to issues and CAPA

The risk register is its own table and is **not** linked to non-conformances or their corrective/preventive actions in code — a risk does not spawn an issue, and closing an issue does not touch a risk. They're complementary: an [issue](/docs/reference/quality.md) records a defect that already happened and drives it to closure through workflow tasks, while a risk register entry is forward-looking, capturing something that *might* go wrong (or an opportunity worth pursuing) so you can weigh and treat it before it does. Use the risk register for proactive assessment and the issue system for reactive containment.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.