docs/references/data/app-state-overview.md
app_state is a SQLite-backed key-value table holding durable internal markers:
the app's record of one-time work or reconciliation generations it has already
applied. Losing a value does not directly delete user data, but may repeat an
expensive migration, seed, or metadata reconciliation.
Write to app_state only when all three hold:
| Question | Required answer |
|---|---|
| Is this internal app/module state, not a user-facing setting? | Yes |
| Must it survive restarts? | Yes |
| Would losing it repeat completed setup or reconciliation work? | Yes |
Otherwise use another system:
| Data | System |
|---|---|
| User-facing setting | PreferenceService |
| Regenerable / silently rebuildable | CacheService |
| Business data from user activity | DataApiService |
| Process-level flag needed before lifecycle | BootConfigService |
src/main/data/db/schemas/appState.ts:
| Column | Type | Notes |
|---|---|---|
key | text, PK | <scope>:<name> (see Key Naming) |
value | text (JSON) | shape owned by the consumer |
description | text, optional | human-readable note on the key's purpose |
createdAt / updatedAt | timestamps | updatedAt doubles as applied-at |
There is no shared service. Each owner reads and writes its own key through the
database handle already available to that owner. Migration receives its
dedicated migration DB; seeding uses the boot database; file metadata
reconciliation uses DbService. Sharing the table does not make keys a
cross-domain API.
app_state read.<scope>:<name>, where scope identifies the owner module (reuse its loggerService context or service name).Every key currently in app_state. Add a row when introducing a key.
| Key | Owner | Value shape | Notes |
|---|---|---|---|
seed:<name> | SeedRunner | { version: string } | Seeding journal, one row per seeder. See Database Seeding Guide. |
seedRunner:bootstrapCompleted | SeedRunner | { completedAt: number } | Bootstrap-window marker — set after the first fully-successful seeding pass; bootstrap-only seeders never run once present. Done-event key (see Disposability exception): never rename once shipped. |
fileManager:contentMetadataGeneration | FileManager | { version: number } | Trust generation for internal-file size / contentHash; a version change atomically invalidates old hashes before background reconciliation. |
migration_v2_status | MigrationEngine | MigrationStatusValue | Grandfathered exception. Bare key predating the <scope>: convention. Do not rename and do not model new keys on it. |
| File | Purpose |
|---|---|
src/main/data/db/schemas/appState.ts | Table schema |
src/main/data/db/seeding/SeedRunner.ts | seed:* owner |
src/main/data/migration/v2/core/MigrationEngine.ts | migration_v2_status owner |
seed:* journal usage