# Esper PoC: Tachograph Driver-Card Activity Evaluation

This PoC intentionally uses only existing imported EventHub source events:

- provider: `TACHOGRAPH`
- source kind: `DRIVER_CARD`
- extraction code: `CARD_ACTIVITY`
- event domain: `DRIVER_ACTIVITY`
- event types: `DRIVE`, `WORK`, `AVAILABILITY`, `BREAK_REST`
- lifecycles: `START`, `END`

It does not introduce canonical-event tables yet. The goal is to prove that Esper can replay one driver and one selected period and produce activity-level and operating-period results.

## Endpoint

```http
GET /api/eventhub/esper-poc/tachograph/driver-card-activities
```

Query parameters:

| Parameter | Required | Example | Meaning |
|---|---:|---|---|
| `tenantKey` | yes | `default` | EventHub tenant key. |
| `driverEntityId` | yes | UUID | Existing `eventhub.event.driver_entity_id`. |
| `occurredFrom` | yes | `2026-04-01T00:00:00Z` | Requested period start. |
| `occurredTo` | yes | `2026-05-01T00:00:00Z` | Requested period end. |
| `guardHours` | no | `24` | Extra loading window before/after requested period. Needed for activities crossing midnight/month boundaries and long rests crossing period boundaries. |
| `significantDrivingMinutes` | no | `3` | DRIVE intervals longer than this threshold count as significant driving periods. |
| `mergeGapSeconds` | no | `60` | Consecutive identical activities are merged if the gap is at most this value. |
| `operatingPeriodSplitRestHours` | no | `7` | A `BREAK_REST` activity longer than this threshold splits operating time periods. |

## Produced levels

### Level 1: Raw

`raw` contains the original point events from `eventhub.event`.

### Level 2: Activities

Esper consumes the raw point events and produces intervals by pairing:

```text
START + END with same sourceRowId, activity type, driver and card slot
```

The service merges consecutive identical activities in the full guard window first, then clips the merged activities to the requested period. This is important because a long `BREAK_REST` crossing the requested boundary must keep its full guard-window duration for operating-period splitting.

## Operating time periods

`operatingTimePeriods` are derived from the merged activity timeline.

A `BREAK_REST` interval splits operating periods when:

```text
activityType = BREAK_REST
and duration > operatingPeriodSplitRestHours
```

The default is 7 hours. With the default, a `BREAK_REST` of exactly 7 hours does not split; it must be longer than 7 hours.

Each operating period contains:

- `sequenceNumber`
- `startedAt`
- `endedAt`
- `durationSeconds`
- `activities`
- `workingOperationTimes`
- `drivingTimeInterruptionEvaluation`
- optional references to the long rest before/after the period

Departure and arrival are evaluated per operating period:

- departure = first significant `DRIVE` interval inside that operating period
- arrival = end of the last significant `DRIVE` interval inside that operating period
- middle/interruption = gaps between significant `DRIVE` intervals inside the same operating period

## Result semantics

- `workResultPerDriver` and `workingOperationTimesPerEmployee` currently use the same PoC summary for the whole requested period.
- `workingSeconds = DRIVE + WORK`.
- `operationSeconds = DRIVE + WORK + AVAILABILITY`.
- `breakRestSeconds` is reported separately.
- Top-level `drivingTimeInterruptionEvaluation` evaluates the whole requested period.
- Each item in `operatingTimePeriods` has its own `drivingTimeInterruptionEvaluation`.

## Current limitations

- Uses the existing source-level `driver_entity_id`, not a canonical employee table.
- Reads only tachograph driver-card activity events.
- Does not merge VU/card duplication.
- Does not persist results; the endpoint returns a PoC calculation response.
- Esper is used for interval creation. Summary, clipping, operating-period split, and merged activity report calculation are implemented in Java for auditability and easier future migration to canonical events.
