---
name: fantasia-sqlite-main
description: >-
  Designs SQLite usage in Fantasia Archive’s Electron main process: file
  locations under userData, native better-sqlite3 module constraints, and migrations.
  Use when editing electron-main database code, schema, or persistence paths.
---

# Fantasia Archive — SQLite in main process

## Canonical schema documentation

- **[docs/database/projectDB.md](../../../docs/database/projectDB.md)** — **`.faproject`** `user_version` (supported max **11**), tables, IPC, Project Settings
- **[docs/database/templateCustomFields.md](../../../docs/database/templateCustomFields.md)** — planned custom fields (not shipped)
- **[docs/database/appUserDataKv.md](../../../docs/database/appUserDataKv.md)** — **`electron-store`** in **`userData`**
- **[docs/database/README.md](../../../docs/database/README.md)** — index

Schema/IPC changes → update docs same commit ([docs-database.mdc](../../rules/docs-database.mdc)).

## Current state

- **`better-sqlite3`** — main process only
- **`.faproject`** SQLite under **`src-electron/mainScripts/projectManagement/`**; renderer via **`window.faContentBridgeAPIs.projectManagement`**
- **E2E paths**: **`e2eSetNextProjectCreatePath`** / **`e2eSetNextProjectOpenPath`** in **`playwrightE2eProjectPaths.ts`**
- **`user_version` max 11** today (**`FA_PROJECT_USER_VERSION_SUPPORTED_MAX`**) — worlds, documents, templates, media (v10 **`internal_type`**: embedded / linked_outside / linked_in_project; no include flag; v11 **`external_embed`** + **`external_type`** **`embed`**), junctions, per-world template layout, per-locale translations, document category/status/tree-order/extra-classes patches; **v6** **`worlds.color_pallete`**→**`color_palette`**; **v7** **`tags`** + **`document_tags`**; **v8** **`document_last_opened`** MRU (Project overview); **v9** media type/link/embed columns; **v10** drop **`internal_is_project_included`** + new internal_type CHECK; **v11** media **`external_embed`** + embed CHECK; Project Settings snapshots via **`saveWorldsSnapshot`**, **`saveDocumentTemplatesSnapshot`**
- **Pre-release flatten**: may squash ladder **to** version **1** for dev resets — [fantasia-flatten-database-schemas](../fantasia-flatten-database-schemas/SKILL.md) (distinct from live supported max **11**)

## Principles

1. **No arbitrary SQL from renderer** — narrow validated preload APIs + IPC ([fantasia-electron-preload](../fantasia-electron-preload/SKILL.md))
2. **Paths**: **`app.getPath('userData')`**; mkdir before open
3. **Native builds**: verify **`yarn quasar:build:electron`** after upgrades
4. **Lifecycle**: deliberate open/close; no leaked handles on dev reload

## Active project DB access (mandatory failsafe)

All active **`.faproject`** reads/writes → **`runWithFaProjectDatabaseForIpcAsync`** / **`runWithFaProjectDatabaseSync`** from **`faProjectDatabaseEnsureConnected.ts`**. ESLint restricts direct **`getFaProjectActiveDatabase`** imports ([fa-project-database-access.mdc](../../rules/fa-project-database-access.mdc)).

### Project settings refresh contract (renderer)

Unlike App Settings (Pinia seed on open), **Project Settings** always reads SQLite on open:

1. **Open**: **`getProjectSettings`** + **`listWorldsForProjectSettings`**
2. **Edit**: local draft until Save
3. **Save**: **`saveProjectSettings`** → KV patch + optional **`saveWorldsSnapshot`**
4. **Errors**: throw → action manager toast
5. **Main**: **`runWithFaProjectDatabaseForIpcAsync`** only

Extend **`propagateFaProjectSettingsToAppConsumers`** when new fields need live UI after save. See **projectDB.md** **Project Settings (renderer ↔ SQLite)**.

- **Mirrored path**: **`faProjectActiveDatabase.ts`** — **`replaceFaProjectActiveDatabase`**, **`closeFaProjectActiveDatabase`**, handle-only close for reconnect
- **Reconnect + retry**: one sync reopen + one handle-only retry on classified SQLite errors; single-flight mutex
- **Optional renderer path**: **`FA_PROJECT_FAILSAFE_IPC`** when main has no mirrored path
- **Session reset**: **`did-start-navigation`** main frame, not same-document — **`faMainWindowWebContentsSessionReset.ts`**

New project-DB IPC → ensure layer + tests under **`projectManagement/_tests/`**.

## Evolution

- Dedicated module under **`mainScripts/`** when replacing stubs; keep **`electron-main.ts`** thin
- Migrations/backup aligned with worldbuilding model — [fantasia-worldbuilding-domain](../fantasia-worldbuilding-domain/SKILL.md)

## Types

Shared types → **`types/`**. See [types-folder.mdc](../../rules/types-folder.mdc).
