# Offline Service

The offline service assembles encrypted content bundles, manages licenses, and
coordinates multi-device synchronization for Lilith clients operating without a
persistent network connection. It ships Fastify endpoints for bundle
creation/download plus a conflict-aware synchronization pipeline backed by
in-memory state and deterministic mocks for repositories and queues.

## Synchronization Workflow

- Devices post change sets to `POST /v1/offline/sync/changes`. The `SyncManager`
  normalizes payloads, applies newer revisions, and queues cache refreshes when
  fresh source URLs are provided.
- Divergent updates produce conflict records with stable IDs. Conflicts expose
  server and incoming metadata (versions, checksums, device IDs) and are
  persisted until resolved.
- Resolutions through `POST /v1/offline/sync/conflicts/:id/resolve` support
  `keep_server`, `accept_client`, or `manual_merge`. Each response now returns
  `final_state`, giving clients the authoritative snapshot after resolution,
  even when the server copy wins.

## Status & Analytics

`GET /v1/offline/sync/status?user_id=…` now includes telemetry enabling the
mobile clients to render dashboards and escalation cues:

- `summary.total_devices` – distinct devices that have synchronized for the
  user.
- `summary.pending_conflicts` / `summary.resolved_conflicts` – live counts for
  triage.
- `summary.last_sync_at_iso` – most recent device handshake timestamp.
- `summary.last_conflict_at_iso` – most recent conflict activity (creation or
  resolution).
- `conflict_log` – capped stream of the latest conflict events
  (`conflict_detected`, `conflict_resolved`) with device attribution, version
  details, and resolution metadata. The log never grows beyond 100 entries per
  service instance.

These analytics are computed without external persistence so the service remains
deterministic in tests. When integrating a real store, mirror the same shapes to
keep clients stable.

## Testing

Run the Jest suite with the repository-standard guards:

```bash
timeout -k 5 120s npx jest --config apps/lilith/svc-offline/jest.config.js --runInBand
```

The suite covers bundle operations, license enforcement, cache orchestration,
conflict lifecycles (including manual merges and server-side resolutions), and
the new analytics summaries.
