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

# Data Model and Work Items

> Nextedy RISKSHEET does not maintain its own data store. Every row in the grid, every cell value, and every link between items maps directly to standard Polarion work items in Siemens Polarion ALM.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

This page builds the mental model you need before touching configuration. It explains the two-entity data model, the distinction between the actual Polarion entities and the visual hierarchy you see in the grid, and the role of the risk item as the central aggregation point that ties context, classification, and mitigations together.

## All Data Lives in Polarion

The first and most important idea: there is no Risksheet database. When you save a cell, the value is written to a Polarion work item field. When you create a row, a new Polarion work item is created. When you link a risk to a mitigation, a Polarion link is created using a configured link role. When you open a baseline, you are reading Polarion's revision history.

This has practical consequences:

* **Authorization** is enforced by Polarion. If a user cannot edit a field in the Polarion tracker, they cannot edit it in Risksheet either.
* **Audit and history** come from Polarion. Every change to a work item is captured in Polarion's revision history; Risksheet does not maintain a parallel log.
* **Search and reporting** use Polarion's search index. Risk items found through Risksheet are the same items found through Polarion queries, LiveReports, or third-party tools.
* **Mandatory fields** are intentionally NOT enforced inside Risksheet. By design, you can leave required fields blank during analysis and have Polarion's workflow validation catch them when the document moves to a later status. To make required columns visible during entry, use a cell decorator to color them — see [Styling and Formatting](/risksheet/guides/styling/index).

<Tip title="Mental Model">
  Think of Risksheet as a spreadsheet view onto Polarion. The spreadsheet has no value of its own without the underlying work items, and editing the spreadsheet is identical to editing the work items directly.
</Tip>

## The Two-Entity Data Model

Risksheet's data model has exactly two entity types, regardless of methodology or industry. Every Risksheet you will ever see is built from these two types of Polarion work items:

1. **Risk items** — the main rows of the grid. Configured under `dataTypes.risk`. Typical work item types: failure modes (Failure Mode and Effects Analysis, FMEA), hazards (Hazard Analysis and Risk Assessment, HARA), threats (Threat Analysis and Risk Assessment, TARA, or STRIDE), risk records, or — in non-risk use cases — requirements.
2. **Task items** — downstream linked work items, one or more per risk item. Configured under `dataTypes.task`. Typical work item types: mitigations, safety requirements, controls, countermeasures, or test cases.

The names "risk" and "task" are naming conventions inside the configuration. They are NOT constraints on what kind of work items you can use. A Risksheet configured with `dataTypes.risk.type: requirement` and `dataTypes.task.type: testcase` becomes a requirements traceability matrix. The grid does not care — it simply renders one type of work item as the main row and another as the downstream relationship.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/-Icoak49xQVOW38R/risksheet/diagrams/concepts/data-model/diagram-1.svg?fit=max&auto=format&n=-Icoak49xQVOW38R&q=85&s=b8aa37fb1a31fef924ced8616d87cbdf" alt="diagram" style={{ maxWidth: "640px", width: "100%" }} width="640" height="260" data-path="risksheet/diagrams/concepts/data-model/diagram-1.svg" />
</Frame>

Every configuration property under `dataTypes.risk` and `dataTypes.task` defines a small contract with Polarion: which work item type to use, which link role connects them, which work item types are eligible as upstream references, and so on. See [Configuration Reference](/risksheet/reference/configuration/index) for the full list.

## The Risk Item as Central Aggregation Point

The risk item is the keystone of Risksheet's data model. It is the row that ties together everything you want to express about a single failure, hazard, threat, or other risk concept. Read each risk item from left to right and it tells a complete story:

1. **Context** — where this risk lives. Upstream link columns (`itemLink`, `multiItemLink`) point back to the function, system, component, or requirement that the risk applies to. Context columns answer "what is this risk a risk of?"
2. **Risk attributes** — the description of the failure itself. Editable Polarion fields on the risk work item: failure mode title, cause, effect of failure, hazard description.
3. **Classification** — how the risk is rated before mitigation. Severity, occurrence, and detection are scored using rating scales backed by Polarion enumerations. A formula then computes an initial classification — for example, an initial Risk Priority Number (RPN), an Automotive Safety Integrity Level (ASIL) grade, or a 2D risk matrix cell.
4. **Mitigations** — what is being done about it. Task items link from the risk row, each typically representing a mitigation, control, safety requirement, or countermeasure. The task item itself is a separate Polarion work item with its own owner, status, and traceability.
5. **Residual risk** — how the risk is rated AFTER mitigation. New severity, new occurrence, new detection — same columns conceptually, but stored in different fields and producing a "new RPN" or "final classification".

The risk item is, in effect, a mapping table: it joins upstream context to downstream mitigations and records the before/after classification of the risk along the way. This is why almost every Risksheet column ultimately attaches to the risk item or to one of its task children — the grid is a flattened, navigable view of that mapping.

| Region of the row      | Typical columns                                      | Backed by                                |
| ---------------------- | ---------------------------------------------------- | ---------------------------------------- |
| Context                | Item, function, system reference                     | Upstream links (itemLink, multiItemLink) |
| Risk attributes        | Failure mode, cause, effect                          | Polarion fields on the risk work item    |
| Initial classification | severity, occurrence, detection, RPN                 | rating fields + a formula                |
| Mitigations            | Mitigation actions, controls, owners                 | Task items (downstream links)            |
| Residual risk          | new severity, new occurrence, new detection, new RPN | rating fields + a formula                |

## Two Senses of "Level": Data Model vs Visual

The word "level" appears twice in the Risksheet vocabulary, with two very different meanings. Confusing them is the single most common source of misunderstanding when a new configuration does not behave as expected.

### Data model levels (always exactly two)

In the data model, there are only two levels: risk items and task items. Both are real Polarion work items. Both are governed by Polarion permissions, workflows, and history. You cannot add a third data model level — the engine does not support it.

### Visual levels (one, two, three, or more — configured by you)

The grid you see can present a hierarchy that looks much deeper than two levels. A typical Design FMEA shows Item → Failure mode → Cause → Effect, which feels like four levels. A Functional Hazard Assessment shows Function → Failure condition → Detail, which feels like three. None of these are extra entities in Polarion. They are produced by **cell merging**.

The mechanism is the `levels` array in the sheet configuration. Each entry defines one visual level, and each column declares which level it belongs to through its `level` property. When consecutive rows have the same value in a level's control column, the cells in that column are merged vertically, producing the visual appearance of a parent row spanning multiple child rows.

```yaml theme={null}
levels:
  - name: Item
    controlColumn: item
    zoomColumn: item
  - name: Failure mode
    controlColumn: failureMode
    zoomColumn: failureMode
  - name: Cause
    controlColumn: systemItemId
    zoomColumn: causes
```

Every level entry must have three properties:

| Property        | Type   | Purpose                                                                                        |
| --------------- | ------ | ---------------------------------------------------------------------------------------------- |
| `name`          | string | Display name in the navigation and zoom menu (for example, "Item", "Failure mode", "Detail")   |
| `controlColumn` | string | Column ID whose value drives cell merging — rows with the same value get merged for this level |
| `zoomColumn`    | string | Column ID used as the target when a user uses zoom or drill-down navigation                    |

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/-Icoak49xQVOW38R/risksheet/diagrams/concepts/data-model/diagram-2.svg?fit=max&auto=format&n=-Icoak49xQVOW38R&q=85&s=0f1801cdbd5db1257bcf0295abbeac08" alt="diagram" style={{ maxWidth: "640px", width: "100%" }} width="640" height="280" data-path="risksheet/diagrams/concepts/data-model/diagram-2.svg" />
</Frame>

### How columns connect to levels

The column `level` property is a one-based integer that points into the `levels` array:

* `level: 1` corresponds to the first entry in `levels` (the outermost grouping)
* `level: 2` corresponds to the second entry
* `level: 3` corresponds to the third entry

Columns that share the same `level` number get **identical** cell merging behavior — that is the practical meaning of "same level". They merge wherever the control column of that level has the same value across rows. Task columns (those bound to `task.*` fields) have no level assigned; they merge by parent risk item plus task ID, which is built-in.

<Info title="Why columns at the same level merge together">
  Because they share a control column. A level says: "merge cells in any column at this level wherever this control column's value is identical in consecutive rows." If you put both "Item" and "Item description" at level 1 with `controlColumn: item`, they will both merge into the same blocks. This is intentional — it produces the appearance of a parent-row whose attributes span all child rows beneath it.
</Info>

### Common misconceptions

<Warning title="Common misconceptions about levels">
  * **"Adding a level adds a new work item type."** No. Levels are display configuration. The data still has two entity types (risk and task) regardless of how many visual levels you define.
  * **"Risksheet aggregates items from multiple documents."** No. A Risksheet is a visualization of a single LiveDoc. It cannot pull work items from other documents based on naming patterns or document hierarchy. If you need cross-document analysis, use a Polarion query, a LiveReport, or branching.
</Warning>

## Visibility and Levels

Defining visual levels is only half of how a row appears in the grid. The other half is visibility: which Polarion work items actually flow into the level at all. Risksheet applies a layered set of filters before any cell merging happens, and understanding that pipeline prevents the most common "why is this item missing?" or "why can't I edit this?" questions.

### What determines whether an item appears

When you open a Risksheet, it loads the risk- and task-type work items that already exist in its LiveDoc — an existing document opens pre-populated with its items, not as a blank grid. From that set, not every work item is necessarily rendered: visibility is the combined result of type filtering, status filtering, permission checks, and level membership.

**Type filtering.** The `dataTypes` configuration defines which work item types are allowed at each tier:

* `dataTypes.risk.type` — work item types displayed as risk items (the main grid rows). Multiple types can be specified as comma-separated values.
* `dataTypes.task.type` — work item types displayed as task/mitigation items (the downstream linked rows). Multiple types can also be specified as comma-separated values.

Work items whose type does not match either `risk.type` or `task.type` are excluded from the grid entirely. This is the most fundamental visibility filter.

**Rejected status filtering.** Work items with a status matching the configured `rejectedStatus` (default: `rejected`) are automatically hidden from the grid. The system applies separate rejected-status rules for risk items and task items. This enables a soft-delete pattern: instead of permanently deleting a risk item, change its workflow status to the rejected one and it disappears from the grid while remaining available for audit and traceability in Polarion.

<Tip title="Soft delete via rejected status">
  Rather than permanently deleting risk items, configure `rejectedStatus` and move unwanted items into that status. They remain in Polarion for history and traceability but no longer clutter the active risk analysis view.
</Tip>

**Permission-based filtering.** Risksheet respects Polarion's security model. Work items the current user lacks read permission for are silently excluded from results — the user simply does not see items they cannot access. This is especially important in regulated environments where role-based access to risk data is mandated.

**Unresolvable item filtering.** Work items that are corrupted, deleted at the repository level, or otherwise unresolvable are automatically excluded to prevent grid errors. This is a defensive mechanism that handles data quality issues silently.

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/-Icoak49xQVOW38R/risksheet/diagrams/concepts/data-model/diagram-3.svg?fit=max&auto=format&n=-Icoak49xQVOW38R&q=85&s=a19fd516d519a03725ad4bf41c89e550" alt="diagram" style={{ maxWidth: "400px", width: "100%" }} width="400" height="400" data-path="risksheet/diagrams/concepts/data-model/diagram-3.svg" />
</Frame>

### Upstream, downstream, and indirectly linked items

Levels are fundamentally about relationships between work items, and the terminology used in Risksheet maps directly to the direction of traceability links:

* **Upstream items** are work items the current row links TO (for example, a failure mode links to a system requirement). They appear in upstream traceability columns, typically configured as `itemLink` or `multiItemLink` column types.
* **Downstream items** are work items that link FROM the current row (for example, mitigation tasks linked to a failure mode via the task role). They appear in task-level columns at the bottom of the hierarchy.

A common source of confusion is the difference between items that are directly linked to a risk item and items that are linked through an intermediary. If a failure mode (Level 2) links to a requirement (Level 1), and that requirement links to a system function, the system function is an indirect link — it is not directly connected to the failure mode.

Standard Risksheet columns can only display directly linked work items. To show items connected through upstream relationships, there are two options:

1. **Server render columns** — Use Velocity scripts to traverse indirect links and render the results as read-only HTML. See [Server Render Columns](/risksheet/reference/columns/server-render-columns) for the Velocity patterns.
2. **`upstreamChains`** — A configuration property (format: `fromType-linkRole-toType`) that automatically builds transitive link chains. This creates actual Polarion links, making the indirect relationships editable. Note that `upstreamChains` only creates links; it never deletes them.

<Warning title="Multi-level display is not transitive">
  Users frequently expect that configuring a Level 2 column will automatically show items linked through Level 1 items. This is not how levels work. Each level displays items that are *directly* linked to the current row's work item. Indirect links require explicit configuration via server render or `upstreamChains`.
</Warning>

### Cross-project item visibility

Risksheet supports displaying work items from other Polarion projects. This is configured via the `project` parameter in the `typeProperties` section of a column or data type definition. When a project ID is specified, Risksheet loads items from that project instead of (or in addition to) the current one.

Cross-project visibility has well-defined limits:

* It works for **directly linked items only**. Indirect links through intermediary work items in other projects require additional configuration, typically server render columns with cross-project Velocity queries.
* The user must have read permissions in the target project. Items the user cannot access are filtered out.
* Workflow status dropdowns correctly load actions for the source project using the `project!workItemId` format, enabling status editing for cross-project items.

### The read-only boundary

Not every visible item is editable. Several factors can make work items or individual columns read-only:

| Condition                                                          | Effect                                                                |
| ------------------------------------------------------------------ | --------------------------------------------------------------------- |
| `readonly: true` in root configuration                             | Entire grid is read-only                                              |
| `downstreamReadonly: true`                                         | Downstream linked items (tasks) from other documents cannot be edited |
| `reviewer: true`                                                   | Reviewer mode restricts editing and shows review-specific controls    |
| Historical revision viewing                                        | Viewing a non-current revision forces read-only mode automatically    |
| Column has `serverRender`                                          | Column is always read-only                                            |
| Column has `formula`                                               | Column is read-only by default                                        |
| System fields (`id`, `status`, `type`, `project`, `outlineNumber`) | Always read-only regardless of configuration                          |
| Permission restrictions                                            | Columns where the user lacks write permission are read-only           |

<Note title="`readonly` vs `readOnly` — casing is intentional">
  The casing differs by level and both are correct. The **root-level** grid flag is lowercase `readonly` (`readonly: true` makes the whole grid read-only). The **column-level** property is camelCase `readOnly` (set on an individual column definition). They are deliberately different keys at their respective levels — neither should be "corrected" to match the other.
</Note>

<Note title="New items and workflow">
  Newly created work items (identified by IDs starting with `*`) have limited functionality until saved. Status dropdowns are disabled for new items because workflow actions only apply to items that exist in Polarion. Save the item first; workflow transitions become available afterwards.
</Note>

### Cell merging revisited

When multiple Level 2 items share the same Level 1 parent, the Level 1 columns merge vertically to span all child rows. This produces the characteristic FMEA layout where a single failure mode description spans multiple cause/effect pairs. The `controlColumn` property on each level determines which column drives the merge grouping: rows with the same value in the control column at a given level are merged.

The visual result is a grid where:

* Level 1 columns span multiple rows, showing the parent item data once.
* Level 2 columns show one row per child item.
* Task-level columns show one row per downstream linked item within each Level 2 group.

### Context menu and item creation

The context menu (right-click on a grid cell) provides options for creating new items at different levels. The menu dynamically generates options from the `levels` array where `showInMenu` is `true`. Only levels configured for menu visibility appear as creation options.

The context menu also provides:

* **Open Row Item** — navigates to the current row's work item in Polarion's item editor.
* **Open \[Column] Item** — opens the linked work item for that column; the menu label embeds the column name (for example **Open Item/Func Item**).
* **Open Task Item** — opens a task work item; the menu label uses the task type name from `dataTypes.task.name` if configured.
* **Remove Row Item** — removes the selected row (only in editable grids).
* **New Level Items** — creates new work items at the selected level (only in editable grids).

### A practical mental model for levels

Think of levels as a telescope with adjustable zoom:

* **Level 1** is the widest view — top-tier items (system functions, hazards, or failure modes depending on your structure).
* **Level 2** zooms in to the children of each Level 1 item — causes, effects, or sub-failure modes.
* **Task level** zooms to the finest detail — mitigation tasks, verification activities, or design changes linked to specific Level 2 items.

Each column in the grid is assigned to exactly one zoom level. When you look at a row, the Level 1 columns show data from the Level 1 parent, the Level 2 columns show data from the Level 2 item, and the task columns show data from the downstream linked task. All three coexist in the same visual row, but they represent data from different work items connected by links.

The `levels` configuration in `risksheet.json` tells Risksheet how many zoom levels exist and which column drives the grouping at each level. The `dataTypes` configuration tells Risksheet which work item types belong to which tier and which link roles connect them.

## Where Data Lives: Fields, Links, and Configuration

When the grid renders, three different sources of data flow into the cells you see:

| Cell source        | What it is                                                                                      | Where it lives                                              |
| ------------------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Field value        | A column whose `bindings` matches a Polarion field reads that field's value                     | Polarion work item field                                    |
| Linked field value | A column with `bindings: linkedItem.fieldId` reads from an upstream or downstream linked item   | Different Polarion work item, reached via link role         |
| Formula result     | A column with a `formula` runs JavaScript to compute the value from other cells in the same row | Computed at display time, optionally stored back to a field |

Columns declare these mappings using the `bindings` property (note: plural — `bindings`, not `binding`). Examples:

```yaml theme={null}
columns:
  - id: title
    header: Failure mode
    bindings: title
    type: string
    level: 2
  - id: sev
    header: Severity
    bindings: severityRating
    type: rating:severityEnum
    level: 2
  - id: hazard
    header: Hazard
    bindings: hazard.title
    type: string
    level: 1
  - id: rpn
    header: RPN
    formula: commonRpn
    type: int
    readOnly: true
    level: 2
```

Three binding patterns are possible:

* `bindings: title` — a direct field on the risk work item.
* `bindings: hazard.title` — a field on a linked item. Read-only by default because the value belongs to a different work item.
* `bindings: task.$item` — the entire task work item, used by server-rendered columns that need full Velocity access.

For an enum or rating column, you also declare the enum identifier in the column `type`:

```yaml theme={null}
- id: severity
  header: Severity
  bindings: severityRating
  type: rating:severityEnum
- id: detectionMethod
  header: Detection methods
  bindings: detectionMethods
  type: multiEnum:detectionMethodsEnum
```

The enum identifier (`severityEnum`, `detectionMethodsEnum`) points to a Polarion enumeration defined in **Administration → Enumerations**, not to something inside the sheet configuration. Risksheet asks the server to load the enumeration values at runtime; this is why custom rating scales are configured in Polarion administration first, then referenced from the column.

<Info title="Verify in application">
  The exact set of column types that can appear in your project depends on the field types defined for the configured work item types. Risksheet auto-detects the column type from the Polarion field type when `type` is omitted, but explicit declaration is recommended for clarity and to override defaults.
</Info>

## Linking: Upstream Context and Downstream Mitigations

The two main link directions create the "left side" and "right side" of the risk item story.

**Upstream links** (left side) attach a risk to its context. They are configured on individual columns through `typeProperties`:

```yaml theme={null}
- id: hazard
  header: Hazard
  bindings: hazard
  type: itemLink
  typeProperties:
    linkRole: relates_to
    linkTypes: hazard
    document: 02 - Risk Management File/Harms Library
  level: 1
```

The configuration above tells Risksheet that the "Hazard" column links to existing work items of type `hazard` from a shared library document. New entries created inline (if `canCreate` allows) go to that document.

**Downstream links** (right side) attach a risk to its mitigations. They are configured under `dataTypes.task`:

```yaml theme={null}
dataTypes:
  task:
    type: mitigation
    role: mitigates
    name: Mitigation
    zoomColumn: mitigationTitle
```

A single risk row can have many task rows beneath it; the grid renders each task as a "child" row visually grouped with its parent risk. The link itself is a normal Polarion link with the configured role.

For deeper explanations of these mechanics, see [Traceability and Linking](/risksheet/concepts/traceability). For the configuration reference, see [Configuration Reference](/risksheet/reference/configuration/index).

## What About Required Fields, Branching, and Cross-Document References?

A few behaviors that surprise new users — all consequences of "data lives in Polarion":

* **Required Polarion fields are not enforced during entry.** This is by design. Risksheet keeps the entry surface fast and forgiving; required-field validation belongs to a later workflow status, or to a visual highlight applied through a cell decorator.
* **Read-only branches.** When a document is branched, the branched copy shows the original risk items as read-only references by default. If `editableReferencedWorkItems` is enabled at the project level, those referenced items become editable in the branch. There is currently no way to reference individual risks across non-branched documents — branching is the supported mechanism for shared risk content.
* **One document per Risksheet.** Risksheet is the visualization of a single LiveDoc. It does not aggregate items across multiple documents based on filename suffixes, document hierarchy, or query results. If a workflow needs cross-document analysis, the answer is either to combine the source documents, use Polarion queries, or open multiple Risksheets side-by-side.

## How This Shapes Your Configuration Decisions

If you keep the two-entity / two-sense-of-level model in mind, several configuration decisions become clearer:

1. **Choose the risk work item type carefully.** Whatever you put under `dataTypes.risk.type` becomes the row, the search target, the access control unit, and the audit subject. Switching types later is expensive.
2. **Pick task work item types intentionally.** Each task type carries its own custom fields, workflow, and link roles. Multiple downstream types are supported (comma-separated in `dataTypes.task.type` since recent versions), but each adds complexity.
3. **Use levels for visual structure, not data structure.** If you find yourself wishing for a "third data model level", you are probably looking for either a deeper visual hierarchy (add to `levels`) or an upstream library (add an `itemLink` column with `typeProperties.document`).
4. **Use views, not extra documents, for different perspectives.** Saved views let the same underlying data appear with different column subsets for identify-failures vs initial-ranking vs final-assessment stages.

For practical guidance on putting this model to work, see [Column Configuration](/risksheet/guides/columns/index), [Risk Management](/risksheet/guides/risk-management/index), and [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy).

<LastReviewed date="2026-06-24" />
