# SQLite schema

One table, a subset of Android `android.provider.CallLog.Calls`. The DB lives
at `$XDG_DATA_HOME/liberux/calllog/calllog.db` (WAL mode).

## `calls`

| Column        | Type      | Notes                                                        |
| ------------- | --------- | ------------------------------------------------------------ |
| `_id`         | INTEGER PK| Autoincrement.                                               |
| `number`      | TEXT      | Dialed/caller number as presented. May be empty (withheld).  |
| `date`        | INTEGER   | Call start, ms since the Unix epoch (`Calls.DATE`).          |
| `duration`    | INTEGER   | Talk time in whole seconds (`Calls.DURATION`); 0 if unanswered.|
| `type`        | INTEGER   | `Calls.TYPE` — see below.                                    |
| `new`         | INTEGER   | Unread flag (`Calls.NEW`); 1 on insert, cleared by `MarkAllRead`. |
| `cached_name` | TEXT      | Name snapshot at insert (`Calls.CACHED_NAME`); NULL if unknown. |
| `created_at`  | INTEGER   | Row creation, ms since epoch.                                |

Indexes: `idx_calls_date` on `date DESC` (the recents query), partial
`idx_calls_new` on unread rows (missed-call badge).

### `type` values (`CallLog.Calls.TYPE`)

| Value | Meaning   |
| ----- | --------- |
| 1     | Incoming  |
| 2     | Outgoing  |
| 3     | Missed    |
| 4     | Voicemail |
| 5     | Rejected  |
| 6     | Blocked   |

The daemon stores `type` verbatim and does not interpret it, so the Android
Translation Layer round-trips it losslessly; native clients map it to their own
direction/outcome model.

## Migrations

`meta(key, value)` holds `schema_version`. Migrations are an ordered
`(version, sql)` list applied in a single transaction each; shipped migrations
are never edited.
