---
title: Opportunities (CRM Deals)
feature: true
featureGroup: core
featureState: beta
description: Sales opportunities with pipeline stages, amounts and contact linking — part of the CRM pack
date: 2026-05-06
---

The **Opportunity** type represents a sales deal — a potential revenue object that moves through a pipeline. Without opportunities a CRM is just a contact database; with them it tracks the actual sales process.

Opportunities ship as part of the **CRM pack** (`crm-pack`) alongside Contacts and Emails. They can be installed standalone via the **Opportunities** module if you only need the deal pipeline without the rest of the CRM.

## When to use

- Tracking sales deals through stages from lead to closed-won/closed-lost
- Linking revenue forecasts to specific contacts and companies
- Reporting on pipeline value, win rates and expected close dates

## Schema

The schema lives in `packages/shared/src/typesystem/types/opportunity.ts` and is registered as the schema extension `opportunities:v1` in `packages/shared/src/typesystem/schema-extensions.ts`.

| Property            | Type   | Required | Description                                                                           |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------------- |
| `name`              | string | yes      | Short, human-readable name of the deal                                                |
| `amount`            | number | no       | Expected revenue amount                                                               |
| `currency`          | string | no       | ISO 4217 currency code: `EUR` (default), `USD`, `GBP`, `CHF`                          |
| `stage`             | enum   | yes      | One of `lead`, `qualified`, `proposal`, `negotiation`, `won`, `lost` (default `lead`) |
| `probability`       | number | no       | Probability of closing the deal, expressed as a percentage (0–100)                    |
| `expectedCloseDate` | number | no       | Expected close date as a Unix timestamp in milliseconds                               |
| `company`           | string | no       | Free-text company name (autocomplete-enabled)                                         |
| `notes`             | string | no       | Free-form notes                                                                       |

`name` and `stage` are the only required fields. The default stage is `lead` and the default currency is `EUR`.

## Pipeline stages

The default pipeline ships with six stages:

| Value         | German       | English     |
| ------------- | ------------ | ----------- |
| `lead`        | Lead         | Lead        |
| `qualified`   | Qualifiziert | Qualified   |
| `proposal`    | Angebot      | Proposal    |
| `negotiation` | Verhandlung  | Negotiation |
| `won`         | Gewonnen     | Won         |
| `lost`        | Verloren     | Lost        |

Stages are stored as a configurable enum on the type. Once the type is created in a project the project owner can customise the list via the regular type-editor flow.

## Relations

When the Opportunity type is installed alongside a Contact type from the same install batch, the install process wires them up automatically (see `packages/shared/src/templates/extensions/opportunity.type.ts`):

`linksConfiguration` is enabled, so emails, notes, calendar events and tasks can be linked to an Opportunity through the standard relations system — not only to a Contact.

## Backoffice page

Installing the **Opportunities BOM** extension adds a navigation entry at `/opportunities` with a data view showing the columns:

`name`, `company`, `stage`, `amount`, `probability`, `expectedCloseDate`

The page uses the standard widget framework and inherits the same filtering, sorting and bulk-action behaviour as other backoffice modules.

## Installation

The Opportunity module is available in the store as a standalone module and is pre-selected in the **CRM pack**:

```ts
// packages/shared/src/templates/store.collections.ts
modules: [FeatureName.CONTACT, FeatureName.OPPORTUNITY, FeatureName.EMAIL]
```

| Identifier                                | Purpose                                       |
| ----------------------------------------- | --------------------------------------------- |
| `FeatureName.OPPORTUNITY`                 | Opportunities module                          |
| `FeatureExtensionName.OPPORTUNITIES_TYPE` | Creates the Opportunity data type             |
| `FeatureExtensionName.OPPORTUNITIES_BOM`  | Adds the `/opportunities` navigation page     |
| `FeatureRef.OPPORTUNITIES_TYPE`           | Reference for the created type entity         |
| `FeatureRef.OPPORTUNITIES_BOM`            | Reference for the created BOM compound widget |
| `FeatureRef.OPPORTUNITIES_BOM_NAV_ENTRY`  | Reference for the created navigation entry    |

Existing CRM projects can install the new module from the store at any time — no migration is required because the type and BOM are created on demand by the store install flow rather than baked into existing tenant data.

## Duplicate detection

Duplicate detection is enabled with a 0.85 threshold against the `name` and `company` fields. Two deals named "Q4 Renewal" for the same company are flagged as likely duplicates at import or creation time.
