> ## 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.

# Issues (non-conformances)

> How Alforse logs a non-conformance, drives it through a configurable workflow of actions and approvals, and dispositions the affected material before closing.

An **issue** is a non-conformance record containing a defect or deviation and the work required to resolve it. Issues belong to the `quality` module and carry an `nc`-prefixed internal ID plus the user-facing `nonConformanceId`. See the [quality overview](/docs/reference/quality.md#issues) for broader module context.

Create an issue from the issue list, MES, or Slack. Alforse can also create one automatically when an [inbound inspection](/docs/reference/quality.md#inbound-inspection) rejects a lot. All sources use the same lifecycle.

## The lifecycle

A `nonConformanceStatus` has three values. A new issue defaults to **"Registered"**; **"Closed"** is terminal and locks the record.

<details>
  <summary>**Registered**</summary>

  The issue exists but no one has picked it up. The DB default for a new `nonConformance`. Editable.
</details>

<details open>
  <summary>**In Progress**</summary>

  Someone is working it. An issue auto-advances here the first time a user types into a task note while still Registered, or when you click **"Start"** in the header.
</details>

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

  Resolved and locked. `isIssueLocked(status)` is true only for Closed, which blocks edits to the issue and its task assignments. Closing clears the assignee and stamps `closeDate`. **"Reopen"** sends it back to Registered.
</details>

The header buttons drive these transitions, all gated by the `quality` update permission: **"Start"** (Registered → In Progress), **"Complete"** (In Progress → runs `closeIssue`), and **"Reopen"** (In Progress or Closed → Registered). The reopen path is why Closed isn't a dead end. It just re-opens the record for more work.

NOTE

**One issue, many pieces of material**

The issue header holds the priority, source, type, and workflow. The *affected material* lives in a separate junction (`nonConformanceItem`), so a single issue can cover several items and several tracked lots or serials, each dispositioned on its own. The header status is not the same thing as a per-item disposition.

## Header fields

Every issue carries a small set of classification fields. Type and location are required; the rest have defaults or are optional.

FieldType

<details>
  <summary>**Priority**required`Low | Medium | High | Critical`</summary>

  How urgent. Defaults to **"Medium"**.
</details>

<details>
  <summary>**Source**required`Internal | External`</summary>

  Where the defect originated. Defaults to **"Internal"**. External covers supplier- and customer-side non-conformances.
</details>

<details>
  <summary>**Type**required</summary>

  A configurable category (`nonConformanceType`) — your own list, not a fixed enum.
</details>

<details>
  <summary>**Workflow**</summary>

  An optional `nonConformanceWorkflow` that pre-seeds the issue's priority, source, required actions, approvals, and a document template. See below.
</details>

<details>
  <summary>**Location**required</summary>

  The site the issue is raised against.
</details>

<details>
  <summary>**Open / Due / Close date**</summary>

  `openDate` is required; `dueDate` is optional; `closeDate` is stamped automatically on close.
</details>

<details>
  <summary>**Quantity**</summary>

  The affected quantity, optional at the header level.
</details>

## Workflows: the 8D and its cousins

A **workflow** is a reusable template, not a state machine. It defines initial rich-text content, priority, source, required actions, and approval requirements. Selecting a workflow copies those values into the new issue.

Alforse models 8D as a workflow whose required actions cover the eight disciplines. 8D behavior is not hard-coded; custom workflows use the same action model.

## Required actions and their system categories

Each issue references a set of **required actions** (`requiredActionIds`), and the moment the issue is set up, Alforse materializes one **action task** (`nonConformanceActionTask`) per required action, numbered by sort order. Those tasks are the checklist the team works through.

A required action can carry a `systemType` that classifies what kind of action it is. There are five:

FieldType

<details>
  <summary>**Containment**</summary>

  The immediate action that quarantines affected stock or work before the root cause is known. Drives the issue's containment status (below).
</details>

<details>
  <summary>**Corrective**</summary>

  The fix for a confirmed root cause.
</details>

<details>
  <summary>**Preventive**</summary>

  The action that stops the problem recurring elsewhere.
</details>

<details>
  <summary>**Verification**</summary>

  Confirms the corrective and preventive actions actually worked.
</details>

<details>
  <summary>**Communication**</summary>

  Notifies the affected party, e.g. a customer.
</details>

The five system actions (Containment Action, Corrective Action, Preventive Action, Verification, Customer Communication) are seeded per company and **protected**: a database trigger blocks deleting them or changing their `systemType`, and each is unique per company. Any action you add yourself has no `systemType` and is fully editable.

NOTE

**Containment status is derived, not stored**

The `issues` view computes a **containment status** from the action tasks. It reads **"Contained"** when a Containment-type task is In Progress or Completed, **"Uncontained"** when a Containment task exists but hasn't started, and **"N/A"** when the issue has no containment task at all. You don't set it. It follows the work.

### Working the tasks

Action tasks run their own small lifecycle: **"Pending"** → **"In Progress"** → **"Completed"**, with **"Skipped"** as an off-path exit. Tasks start Pending and do *not* auto-start. Completing a task stamps its completed date. A completed or skipped task can be reopened back to Pending. Tasks can be reordered, given due dates, and tied to specific processes, and a supplier-facing action task can be shared externally as a **SCAR** (Supplier Corrective Action Request) report.

The SCAR is a private, login-free link the supplier opens to respond. They see the non-conformance details, the current status, and the action tasks assigned to them — not the rest of the issue: dispositions, approvals, and closure stay internal. For each task the supplier can update the status and write notes in an editor that auto-saves as they type; entering notes on a **"Pending"** task promotes it to **"In Progress"** automatically. Once the issue is **"Closed"**, the SCAR locks and the supplier can no longer make changes. Whoever holds the URL can open it, so send it only to the supplier contact.

## Approvals and the Material Review Board

Beyond actions, an issue can require **approvals**. The only approval requirement Alforse ships is MRB (Material Review Board). Adding it materializes an approval task and, when MRB is newly required, seeds two **reviewers** with titles **"Engineering"** and **"Quality"**. Remove MRB and those seeded reviewers are cleared; reviewers you added by hand are left alone. A reviewer is just a title on the issue. You manage the list inline on the issue.

## Dispositions: deciding the material's fate

Closing an issue is where the affected material gets resolved. Each `nonConformanceItem` row carries a disposition — the decision about what to do with that material. The database enum has more values than the UI exposes; the active picker is a deliberate subset of five:

FieldType

<details>
  <summary>**Pending**</summary>

  Not yet decided. The default. **Blocks closing** the issue if the row has linked material.
</details>

<details>
  <summary>**Return to Supplier**</summary>

  Send it back. On close, linked tracked entities flip to **Rejected** and a Negative Adjustment ledger entry is written.
</details>

<details>
  <summary>**Rework**</summary>

  Fix it and use it. On close, linked entities return to **Available**.
</details>

<details>
  <summary>**Scrap**</summary>

  Write it off. On close, linked entities flip to **Rejected** with a Negative Adjustment ledger entry.
</details>

<details>
  <summary>**Use As Is**</summary>

  Accept the deviation. On close, linked entities return to **Available**.
</details>

HEADS UP

**A Pending disposition on linked material blocks closing**

`closeIssue` runs a preflight over every affected-item row that has linked tracked entities. It refuses to close — *"Cannot close: Disposition is still Pending"* — if any such row is still Pending, if the linked quantities don't sum to the row quantity, or if a linked entity is missing or already Consumed. Only once the plan is clean does it stamp each entity's outcome and set the issue **"Closed"**. A row with no linked material is not gated: you don't have to disposition what you never traced.

## What an issue can point at

Typed associations link an issue to **items**, **customers**, **suppliers**, **job operations**, **purchase-order lines**, **sales-order lines**, **shipment lines**, **receipt lines**, **tracked entities**, and **inbound inspections**. These links provide traceability to the source record and support derived supplier-quality metrics.

From the issue header you can also spin up a [change notice](/docs/reference/change-orders.md) directly, carrying the issue across as its source, when the fix is an engineering change rather than a one-off disposition.

## Related

**Quality**

The module overview: issues, inbound inspection, gauges, documents.

[Open](/docs/reference/quality.md)

**Calibration**

Gauges and calibration-due tracking, the other side of quality.

[Open](/docs/reference/calibration.md)

**Risk register**

Risks and opportunities tracked by source, alongside non-conformances.

[Open](/docs/reference/risks.md)

**Change notices**

Turn an issue into an engineering change.

[Open](/docs/reference/change-orders.md)


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