# Streak Progress

Streak Progress records the **overall state** of a single end user's engagement with a specific streak. It tracks how many periods the user has completed so far, whether the streak is still alive, and key lifecycle timestamps.

:::info
Streak Progress records are **system-managed** — they are created and updated automatically as `Streak Log` entries are processed. They cannot be created, updated, or deleted via the API.
:::

The **Streak** defines the rules (aggregation method, period, target value, milestones). The **Streak Progress** is the running summary of a specific user's journey against those rules. Individual period-level detail lives in **Streak Logs**.

---

## How it works

1. **First log entry arrives** — when a `Streak Log` is created for a user on a streak for the first time, a Streak Progress record is automatically created with `streakProgressStatus: in_progress` and `streakStartedAt` stamped to `activityAt` passed in the StreakLog API.
2. **Progress accumulates** — each period the user meets the aggregation target, `currentProgressValue` increments.
3. **Period missed** — if the user fails to meet the aggregation target in a period, the status transitions to `broken` and `streakBrokenAt` is stamped.
4. **Streak completed** — when `currentProgressValue` reaches the streak's total required periods, the status transitions to `completed` and `streakCompletedAt` is stamped as per `activityAt` field of the StreakLog API.
5. **Task progress surfaced** — when listing Streak Progress records, the response also includes the current **Task Progress** (`taskProgress`) inline, giving a full picture of this-period activity without a separate request.

---

## Fields

### Identity & linking

| Field | Type | Description |
|---|---|---|
| `streakId` | UUID | ID of the parent streak this progress record belongs to. Indexed. |
| `uniqueIdentifier` | string | Auto-generated composite key: `streakId + ownedById`. This field is unique when `streakProgressStatus` value is `in_progress`. |

### Progress & status

| Field | Type | Default | Description |
|---|---|---|---|
| `currentProgressValue` | number | `0` | The number of periods the user has successfully completed so far in this streak. |
| `streakProgressStatus` | enum | `in_progress` | Current status of the streak for this user. See [statuses](#status-values) below. |

### Timestamps

| Field | Type | Description |
|---|---|---|
| `streakStartedAt` | datetime | When the user first engaged with this streak. It takes value from the `activityAt` field in the StreakLog API. |
| `streakCompletedAt` | datetime | Stamped with the `activityAt` value of the StreakLog API when `streakProgressStatus` transitions to `completed`. |
| `streakBrokenAt` | datetime | Stamped when `streakProgressStatus` transitions to `broken`. |
| `lastTaskContributionAt` | datetime | Timestamp of the most recent `activityAt` field of the StreakLog entry processed for this user. |
| `lastTaskCompletedAt` | datetime | Timestamp of the most recent `activityAt` field of the StreakLog in which the user fully met the aggregation target. |

### Ownership

| Field | Type | Description |
|---|---|---|
| `ownedById` | UUID | ID of the end user this progress record belongs to. |
| `ownedBy` | object | Read-only joined user object. |

---

## Status values

| Status | Meaning |
|---|---|
| `in_progress` | The streak is active — the user has not yet completed all required periods, and has not missed a period. |
| `completed` | The user has met the aggregation target for every required period — the streak is won. |
| `broken` | The user missed a required period — the streak is lost and cannot be recovered. |

---

## The `taskProgress` field

When you list Streak Progress records, the response automatically includes a `taskProgress` object inline. This gives a real-time view of the user's activity in the **current period** without needing a separate API call.

```json
{
  "id": "...",
  "streakId": "a1b2c3d4-...",
  "currentProgressValue": 3,
  "streakProgressStatus": "in_progress",
  "streakStartedAt": "2026-03-15T08:00:00Z",
  "streakCompletedAt": null,
  "streakBrokenAt": null,
  "lastTaskCompletedAt": "2026-04-09T00:00:00Z",
  "lastTaskContributionAt": "2026-04-09T14:30:00Z",
  "taskProgress": {
    "periodKey": "daily_2026-04-10",
    "currentProgressValue": 42.50,
    "taskProgressStatus": "in_progress"
  },
  "ownedById": "user-uuid-here"
}
```

> The `taskProgress` shows today's accumulated value (`42.50`) toward the period target — useful for real-time progress bars in the end-user widget.

---

## Real-world examples

**🛍️ E-commerce — 7-day daily spend streak**

A user is on day 4 of a 7-day streak requiring $50+ spend each day:

```json
{
  "streakId": "a1b2c3d4-0000-0000-0000-000000000000",
  "currentProgressValue": 3,
  "streakProgressStatus": "in_progress",
  "streakStartedAt": "2026-04-07T09:00:00Z",
  "streakCompletedAt": null,
  "streakBrokenAt": null,
  "lastTaskCompletedAt": "2026-04-10T00:00:00Z",
  "lastTaskContributionAt": "2026-04-10T14:20:00Z",
  "taskProgress": null,
  "ownedById": "user-uuid-here"
}
```

>The user has completed the 3rd day streak and is on 4th day with zero progress on 4th day

---

**☕ Food & Beverage — 5-visit weekly streak (completed)**

A user successfully completes a 4-week streak requiring 3 café visits per week:

```json
{
  "streakId": "b2c3d4e5-0000-0000-0000-000000000000",
  "currentProgressValue": 4,
  "streakProgressStatus": "completed",
  "streakStartedAt": "2026-03-16T10:00:00Z",
  "streakCompletedAt": "2026-04-10T18:45:00Z",
  "streakBrokenAt": null,
  "lastTaskCompletedAt": "2026-04-09T00:00:00Z",
  "lastTaskContributionAt": "2026-04-09T11:10:00Z",
  "taskProgress": {
    "periodKey": "2026-15",
    "currentProgressValue": 3,
    "taskProgressStatus": "completed"
  },
  "ownedById": "user-uuid-here"
}
```

---

**🏋️ Fitness — monthly activity streak (broken)**

A user missed their February activity target in a 3-month streak:

```json
{
  "streakId": "c3d4e5f6-0000-0000-0000-000000000000",
  "currentProgressValue": 1,
  "streakProgressStatus": "broken",
  "streakStartedAt": "2026-01-01T00:00:00Z",
  "streakCompletedAt": null,
  "streakBrokenAt": "2026-03-01T00:00:00Z",
  "lastTaskCompletedAt": "2026-01-31T00:00:00Z",
  "lastTaskContributionAt": "2026-02-14T09:30:00Z",
  "taskProgress": null,
  "ownedById": "user-uuid-here"
}
```

> The user completed January (`currentProgressValue: 1`) but failed to hit the February target, so the streak broke on 1 March when the new period opened.

---

## Fetching a user's streak progress

End users can query their own progress. Admins can query all records.

**As an end user — get your progress on a specific streak:**

```http
GET /api/v1.0/schema/streak_progress/record?filters={"operator": "and", "conditions": [{"operator": "and", "conditions": [{"fieldSlug": "streakId", "operator": "equals", "fieldValue": "<Streak Id>"}]}]}
x-enduser-access-token: <token>
x-account-id: <account-id>
```

**As an admin — list all progress records for a streak:**

```http
GET /api/v1.0/schema/streak_progress/record?filters={"operator": "and", "conditions": [{"operator": "and", "conditions": [{"fieldSlug": "streakId", "operator": "equals", "fieldValue": "<Streak Id>"}]}]}
x-api-key: <your-api-key>
x-api-secret: <your-api-secret>
```

---

## Access & permissions

| Caller | Allowed operations | Notes |
|---|---|---|
| Admin | GET · LIST | Read-only — no CREATE, UPDATE, or DELETE |
| End user | GET · LIST | Can only read their own progress records |
| Guest user | *(none)* | Not accessible to unauthenticated callers |

:::warning
Streak Progress records **cannot be created, updated, or deleted** via the API. They are managed exclusively by the platform as `Streak Log` entries are processed.
:::

---

## Related resources

| Resource | Description |
|---|---|
| [Streak](/streak) | The parent streak configuration that this progress record belongs to |
| [Streak Log](/streak_log) | Individual period-level log entries that drive progress updates |
| [Milestone](/milestone) | Reward checkpoints linked to the parent streak |
| [Reward Log](/reward_log) | Reward entries issued when a milestone threshold is crossed |

---

## API reference

See the [API Reference](/api/streak-progress) for full request/response schemas and interactive examples for:

- `GET /schema/streak_progress/record` — list streak progress records
- `GET /schema/streak_progress/record/{id}` — get a streak progress record by ID
