| 1 |
# Data Export |
| 2 |
|
| 3 |
GoingsOn stores everything in a SQLite database on your machine. You can take that data out at any time, in formats that other tools can read or that you can inspect yourself. |
| 4 |
|
| 5 |
## Export formats |
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
| JSON (full) | Projects, tasks, events, emails, contacts | `.json` | Inspection, migration, scripted processing | |
| 10 |
| Backup | Same as JSON (full) | `.json.gz` | Round-trip restore into a fresh install | |
| 11 |
| CSV (tasks) | Tasks only | `.csv` | Spreadsheets | |
| 12 |
| ICS (calendar) | Events only | `.ics` | Apple Calendar, Google Calendar, Outlook | |
| 13 |
| Raw SQLite | Everything | `goingson.db` | Direct copy of the database file | |
| 14 |
|
| 15 |
JSON and Backup share one schema; Backup is the same JSON gzipped. CSV and ICS are lossy conversions for interop with other tools. |
| 16 |
|
| 17 |
The raw SQLite file lives in the Tauri app-data directory. You can copy it like any other file; this is the most complete export possible. |
| 18 |
|
| 19 |
## JSON schema |
| 20 |
|
| 21 |
A JSON export is a single object with these top-level fields: |
| 22 |
|
| 23 |
```json |
| 24 |
{ |
| 25 |
"version": "1.1", |
| 26 |
"exportedAt": "2026-06-02T14:30:00Z", |
| 27 |
"projects": [ ... ], |
| 28 |
"tasks": [ ... ], |
| 29 |
"events": [ ... ], |
| 30 |
"emails": [ ... ], |
| 31 |
"contacts": [ ... ] |
| 32 |
} |
| 33 |
``` |
| 34 |
|
| 35 |
- `version` is the export-schema version, not the app version. Restore accepts any `1.x` file. |
| 36 |
- `exportedAt` is UTC, ISO 8601. |
| 37 |
- The five arrays are independent. An export with zero contacts but many tasks is well-formed. |
| 38 |
|
| 39 |
Field names use `camelCase`. Timestamps are UTC ISO 8601 (`2026-06-02T14:30:00Z`). IDs are UUIDs (`550e8400-e29b-41d4-a716-446655440000`). |
| 40 |
|
| 41 |
### Entity shapes |
| 42 |
|
| 43 |
The full field list for each entity is the serde-serialized form of the Rust types in `crates/core/src/`. Below is the minimum every entity carries; consult the source for the complete list. |
| 44 |
|
| 45 |
**Project** (`crates/core/src/models/project.rs`) |
| 46 |
```json |
| 47 |
{ |
| 48 |
"id": "...", |
| 49 |
"name": "Q3 Launch", |
| 50 |
"description": "", |
| 51 |
"projectType": "work", |
| 52 |
"status": "active", |
| 53 |
"createdAt": "2026-04-01T10:00:00Z" |
| 54 |
} |
| 55 |
``` |
| 56 |
|
| 57 |
**Task** (`crates/core/src/models/task.rs`) — the densest entity. Required: `id`, `description`, `status`, `priority`, `tags`, `urgency`, `createdAt`. Optional fields cover scheduling (`due`, `scheduledStart`, `scheduledDuration`), recurrence (`recurrence`, `recurrenceRule`, `recurrenceParentId`), workflow (`snoozedUntil`, `waitingForResponse`), linkage (`projectId`, `milestoneId`, `contactId`, `sourceEmailId`), nested data (`annotations`, `subtasks`), and time tracking (`estimatedMinutes`, `actualMinutes`). |
| 58 |
|
| 59 |
**Event** (`crates/core/src/models/event.rs`) — calendar event with start/end times, optional project/contact links, recurrence rule. |
| 60 |
|
| 61 |
**Email** (`crates/core/src/models/email.rs`) — message metadata, addresses, body (text and html), attachments are stored by reference (path, mime, size) — attachment **contents** are not embedded in the JSON to keep file sizes sane. To export attachment payloads, copy the `attachments/` directory next to the SQLite file. |
| 62 |
|
| 63 |
**Contact** (`crates/core/src/contact.rs`) — name, multi-field emails/phones/socials, tags, notes. |
| 64 |
|
| 65 |
### Denormalized display fields |
| 66 |
|
| 67 |
A few fields are duplicated for display convenience and are not authoritative: |
| 68 |
|
| 69 |
- `Task.projectName`, `Task.contactName` — copies of the linked project/contact name at export time. On restore, GoingsOn re-derives these from the linked IDs; if a linked project was deleted before export, the display name still appears but the link won't resolve. |
| 70 |
|
| 71 |
If you're processing exports programmatically, treat IDs as the source of truth and ignore the `*Name` fields. |
| 72 |
|
| 73 |
## Restore |
| 74 |
|
| 75 |
Restoring a `.json.gz` backup goes through one of two modes: |
| 76 |
|
| 77 |
- **Replace all** — clears the existing database, then loads the backup. Use this when restoring onto a fresh install. |
| 78 |
- **Merge** — adds the backup's entities to whatever is already there. Useful for combining devices, but will create duplicates if the same entities exist on both sides (entities are matched by ID; a duplicate task on two devices created independently has two different IDs). |
| 79 |
|
| 80 |
Plain `.json` exports are not restorable through the UI. They are intended for inspection and migration to other tools. If you want a round-trip backup, use the `.json.gz` format. |
| 81 |
|
| 82 |
The restore version check accepts any export with `version` starting `1.`. Future major versions (`2.x`) will require an explicit conversion path. |
| 83 |
|
| 84 |
## Verifying an export |
| 85 |
|
| 86 |
Open the `.json` file in a text editor. You should see: |
| 87 |
|
| 88 |
1. The five top-level arrays match the counts shown in Settings → Data → Export summary. |
| 89 |
2. Every `id` field is a UUID. |
| 90 |
3. Every timestamp ends with `Z` (UTC). |
| 91 |
4. Search for an entity you remember (a task title, a contact name) — it should appear verbatim. |
| 92 |
|
| 93 |
For a `.json.gz` backup, decompress first: `gunzip -k backup.json.gz` produces `backup.json` which you can inspect the same way. |
| 94 |
|
| 95 |
## What's not exported |
| 96 |
|
| 97 |
- **OAuth tokens and email passwords.** Re-authenticate after restoring. This is intentional — credentials should not travel in a portable file. |
| 98 |
- **TOTP secrets.** Same reason. |
| 99 |
- **Cloud sync state.** A restored database starts as if sync had never been configured; re-enable it in Settings → Cloud sync. |
| 100 |
- **Plugin runtime state.** Plugins are loaded fresh from the plugin directory on next launch. |
| 101 |
- **Window state.** Sidebar widths, last view, etc. |
| 102 |
- **Theme files.** Bundled themes ship with the app; custom themes live as separate `.toml` files in the app config directory and can be copied alongside the database if needed. |
| 103 |
|
| 104 |
## Source of truth |
| 105 |
|
| 106 |
The export schema is defined in `src-tauri/src/export/backup.rs::FullExport`. Entity field lists are the serde forms of the structs in `crates/core/src/`. Any drift between this document and the code is a bug in this document — open an issue or PR. |
| 107 |
|