npm package: @ntitle-ai/sdk
Description: Stripe native, low code pricing, plans and feature analytics for SaaS founders.
Author: Ntitle AI
Latest version: 0.2.4

# Feature Tracking State Model

## 1. High-Level States (Feature Lifecycle)

A feature flow typically involves the following **core states**:

| **Context Field**  | **Description**                       | **Example Values**                    |
| ------------------ | ------------------------------------- | ------------------------------------- |
| `feature_name`     | The feature being tracked             | `"subscription_modal"`                |
| `trigger_source`   | What initiated the feature?           | `"navigation_menu"`, `"promo_banner"` |
| `modal_id`         | Identifier for modals (if applicable) | `"upgrade_options"`                   |
| `selected_option`  | If an option was chosen, which one?   | `"premium_plan"`, `"basic_plan"`      |
| `error_code`       | If an error occurs, what was it?      | `"500_INTERNAL_SERVER_ERROR"`         |
| `interaction_type` | What type of user action?             | `"click"`, `"input"`, `"hover"`       |

## Understanding Sub-States

Each parent state can have multiple sub-states that provide important context about _how_ or _why_ a state transition occurred. Here's the logical purpose of each group of sub-states.

### Feature Checked

> Feature checks are a special case of events that are captured when the SDK checks to see if the user is entitled to a feature or has used up their feature allowance. You do not need to track these events manually as they are automatically captured when calling `meterCheck` or `featureCheck`.

- **entitled**: Represents a check from FE or BE to see if the user is entitled to the feature
- **meter**: Represents a check from FE or BE to see if the user has used up their feature allowance

### Feature Initiated

- **user**: Represents intentional, direct actions by the user
- **system**: Represents automated or programmatic triggers of featuresoutside of user control

### Feature Configuration

- **modal**: Represents configuration that interrupts the main workflow with a focused interface
- **inline**: Represents configuration that occurs within the natural flow of the interface

### Feature Interaction

- **selected**: Represents choosing from predefined options or making discrete choices
- **edited**: Represents free-form modifications or custom input

### Feature Progressed

- **advanced**: Represents forward progress through a defined sequence
- **reversed**: Represents backward movement through a defined sequence

### Feature Completed

- **confirmed**: Represents successful, intended completion of the feature flow
- **inaccessible**: Represents completion blocked by business rules or permissions

### Feature Abandoned

- **cancelled**: Represents explicit, intentional abandonment
- **idled**: Represents passive or timeout-based abandonment
- **closed**: Represents interface-level abandonment
- **clicked_away**: Represents indirect or navigation-based abandonment

### Feature Paywalled

- **configured**: Represents setup or customization prior to payment
- **plan_selected**: Represents primary monetization choice
- **frequency_selected**: Represents secondary monetization parameters

### Feature Error

- **validation**: Represents user-correctable input or logic errors
- **system**: Represents technical failures outside of user control

These sub-states help categorize the specific manner in which a state change occurred, enabling more detailed analysis of user behavior and system performance. When tracking events, choose the sub-state that best describes the logical nature of the transition, rather than focusing on the specific UI implementation.

| **Parent State**        | **Sub-State**        | **Event Name**                         | **Example Use Case**                                                    |
| ----------------------- | -------------------- | -------------------------------------- | ----------------------------------------------------------------------- |
| `feature_initiated`     | `user`               | `feature_initiated.user`               | User clicks a button. The common case, used in most cases.              |
|                         | `system`             | `feature_initiated.system`             | System pops a feature e.g., during onboarding.                          |
| `feature_configuration` | `modal`              | `feature_configuration.modal`          | A modal loads to request further information or decision from the user. |
|                         | `inline`             | `feature_configuration.inline`         | A user is asked to provide more data or a decision.                     |
| `feature_interaction`   | `selected`           | `feature_interaction.selected`         | User chooses an option.                                                 |
|                         | `edited`             | `feature_interaction.edited`           | User edits a form field.                                                |
| `feature_progressed`    | `advanced`           | `feature_progressed.advanced`          | User completes a wizard step.                                           |
|                         | `reversed`           | `feature_progressed.reversed`          | User goes back a step.                                                  |
| `feature_completed`     | `confirmed`          | `feature_completed.confirmed`          | Form submitted or confirmation button clicked.                          |
|                         | `inaccessible`       | `feature_completed.inaccessible`       | User's plan or role does not allow them to use the feature.             |
| `feature_abandoned`     | `cancelled`          | `feature_abandoned.cancelled`          | User hits cancel button and backs out of the flow.                      |
|                         | `idled`              | `feature_abandoned.idled`              | User inactive for too long.                                             |
|                         | `closed`             | `feature_abandoned.closed`             | User closes a modal to back out of the flow.                            |
|                         | `clicked_away`       | `feature_abandoned.clicked_away`       | User clicks away to back out of the flow.                               |
| `feature_paywalled`     | `configured`         | `feature_paywalled.configured`         | User selects a number of seats or usage level.                          |
|                         | `plan_selected`      | `feature_paywalled.plan_selected`      | User selects from one of the plans.                                     |
|                         | `frequency_selected` | `feature_paywalled.frequency_selected` | User chooses between month or year.                                     |
| `feature_error`         | `validation`         | `feature_error.validation`             | Form validation failed.                                                 |
|                         | `system`             | `feature_error.system`                 | API call failed.                                                        |

---

## 2. Contextual Metadata (System & Developer Provided)

To enrich events and make analysis easier, each event should include **both system-generated and developer-provided context**, which together provide a complete view of user behavior. System-generated data ensures consistency and captures environmental factors, while developer-provided context adds domain-specific insights that help interpret user intent.

### **System-Generated Context (Captured Automatically)**

| **Context Field**  | **Description**                                   | **Example Values**                            |
| ------------------ | ------------------------------------------------- | --------------------------------------------- |
| `session_id`       | Unique identifier for the user's session          | `"abc123"`                                    |
| `timestamp`        | Event timestamp                                   | `"2025-02-21T12:30:00Z"`                      |
| `device_type`      | Device category                                   | `"mobile"`, `"desktop"`                       |
| `browser`          | Browser type/version                              | `"Chrome 120"`, `"Safari 17"`                 |
| `os`               | Operating system                                  | `"Windows 11"`, `"iOS 17"`                    |
| `network_status`   | Connection quality                                | `"4G"`, `"Wi-Fi"`                             |
| `latency`          | API response time (if applicable)                 | `250ms`                                       |
| `dom_event`        | The raw DOM event associated with the interaction | `{ type: "click", target: "#submit-button" }` |
| `interaction_type` | Extracted from the DOM event                      | `"click"`, `"input"`, `"hover"`               |

---

### **Developer-Provided Context (Captured from Application Logic)**

| **Context Field** | **Description**                                                                            | **Example Values**               |
| ----------------- | ------------------------------------------------------------------------------------------ | -------------------------------- |
| `system_id`       | Unique ID from your Db. This allows events to be tracked through your BE and other systems | `"user_789"`                     |
| `feature_name`    | The feature being tracked. This does not have to be a valid Stripe feature                 | `"awesome_mode"`                 |
| `selected_option` | If an option was chosen, which one?                                                        | `"premium_plan"`, `"basic_plan"` |
| `error_code`      | If an error occurs, what was it?                                                           | `"500_INTERNAL_SERVER_ERROR"`    |