agent: lumotia-rebrand — data dir migration shim + paths.rs rename
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled

Phase 5 of the rebrand cascade per locked decision D1 (migrate in place).

crates/core/src/paths.rs:
- Hardcoded subdir strings renamed: magnotia/Magnotia -> lumotia/Lumotia
  across all four OS branches (Linux XDG + dot-legacy, macOS Application
  Support, Windows LOCALAPPDATA, fallback dot-dir).
- Database filename: magnotia.db -> lumotia.db.
- Test path fixtures renamed: /tmp/magnotia-test -> /tmp/lumotia-test.
- New MigrationStatus enum (Migrated / TargetAlreadyExists / NoLegacyFound).
- New migrate_legacy_data_dir() that probes the platform-correct legacy
  magnotia path, renames it to the lumotia equivalent via fs::rename, and
  also renames magnotia.db -> lumotia.db inside if found. Idempotent: safe
  to call on every boot. Refuses to overwrite an existing lumotia dir to
  protect user data.
- Four new unit tests covering all branches via the test-friendly
  migrate_legacy_data_dir_inner that takes an explicit legacy path.

crates/storage/src/database.rs:
- New migrate_legacy_setting_keys(pool) that renames any settings rows
  with key matching magnotia_* to lumotia_*. Single SQL UPDATE with
  NOT EXISTS guard so it leaves rows alone if a lumotia_ row already
  exists. Re-exported from lib.rs.

src-tauri/src/lib.rs:
- Calls migrate_legacy_data_dir(&app_data_dir()) at the start of setup()
  BEFORE database_path() resolves the now-renamed dir. Logs migration
  outcome to lumotia_startup tracing target.
- Calls migrate_legacy_setting_keys(&db) immediately after init_db
  returns. Logs only when rows are actually renamed.

src-tauri/src/{lib,commands/{diagnostics,rituals,transcripts}}.rs +
crates/storage/src/database.rs:
- All in-code references to magnotia_preferences, magnotia_history (in
  comments), and magnotia_morning_triage_last_shown renamed to lumotia_*.

cargo build --workspace passes. cargo test --workspace: 334 pass, 0 fail
(up from 330; +4 paths::tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 09:21:45 +01:00
parent e2a5feb718
commit 86f83b7a45
7 changed files with 335 additions and 26 deletions

View File

@@ -335,7 +335,7 @@ async fn generate_diagnostic_report_inner(
if opts.include_settings {
out.push_str("## Settings (sanitised)\n\n");
match lumotia_storage::get_setting(&state.db, "magnotia_preferences").await {
match lumotia_storage::get_setting(&state.db, "lumotia_preferences").await {
Ok(Some(json)) => {
out.push_str("```json\n");
out.push_str(&sanitise_preferences_json(&json));

View File

@@ -8,13 +8,13 @@
//!
//! Stored under the existing SQLite settings table via
//! `lumotia_storage::{get_setting, set_setting}` — same bag as
//! `magnotia_preferences`.
//! `lumotia_preferences`.
use lumotia_storage::{get_setting, set_setting};
use crate::AppState;
const LAST_TRIAGE_KEY: &str = "magnotia_morning_triage_last_shown";
const LAST_TRIAGE_KEY: &str = "lumotia_morning_triage_last_shown";
/// Returns the YYYY-MM-DD date string stored on the last successful
/// morning triage dismissal, or `None` if the user has never been

View File

@@ -28,7 +28,7 @@ use crate::AppState;
///
/// Task 2.5 — `starred`, `manualTags`, `template`, `language`, `segmentsJson`
/// were added to back the viewer metadata that previously lived only in the
/// removed `magnotia_history` localStorage cache.
/// removed `lumotia_history` localStorage cache.
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TranscriptDto {

View File

@@ -12,9 +12,13 @@ use sqlx::SqlitePool;
use tauri::Manager;
use tracing_subscriber::EnvFilter;
use lumotia_core::paths::{migrate_legacy_data_dir, MigrationStatus};
use lumotia_core::types::EngineName;
use lumotia_llm::LlmEngine;
use lumotia_storage::{database_path, get_setting, init as init_db, prune_error_log, set_setting};
use lumotia_storage::{
app_data_dir, database_path, get_setting, init as init_db, migrate_legacy_setting_keys,
prune_error_log, set_setting,
};
/// How long to retain `error_log` rows. Pruned once on startup.
/// 90 days is long enough to triage "this happened a few weeks ago"
@@ -97,7 +101,7 @@ async fn save_preferences(
state: tauri::State<'_, AppState>,
preferences: String,
) -> Result<(), String> {
set_setting(&state.db, "magnotia_preferences", &preferences)
set_setting(&state.db, "lumotia_preferences", &preferences)
.await
.map_err(|e| e.to_string())
}
@@ -220,6 +224,29 @@ pub fn run() {
builder
.setup(|app| {
// One-shot legacy data-dir migration: rename ~/.local/share/magnotia
// (and macOS/Windows equivalents) to the lumotia path on first
// launch after the rebrand. Safe to call every boot — idempotent.
let t_migrate = Instant::now();
let new_data_dir = app_data_dir();
match migrate_legacy_data_dir(&new_data_dir) {
Ok(MigrationStatus::Migrated { from, to, renamed_db }) => tracing::info!(
target: "lumotia_startup",
elapsed_ms = t_migrate.elapsed().as_millis(),
from = %from.display(),
to = %to.display(),
renamed_db,
"migrated legacy magnotia data dir to lumotia"
),
Ok(MigrationStatus::TargetAlreadyExists { .. }) => {}
Ok(MigrationStatus::NoLegacyFound) => {}
Err(e) => tracing::warn!(
target: "lumotia_startup",
error = %e,
"legacy data dir migration failed — continuing with new path"
),
}
// Initialise database and startup settings in one runtime entry.
let db_path = database_path();
let (db, init_script) = tauri::async_runtime::block_on(async {
@@ -229,6 +256,25 @@ pub fn run() {
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
tracing::info!(target: "lumotia_startup", elapsed_ms = t0.elapsed().as_millis(), "DB init complete");
// One-shot settings-key migration: rename any leftover
// `magnotia_*` rows from the magnotia era to `lumotia_*`.
// Idempotent; logs only when rows are actually renamed.
let t_keys = Instant::now();
match migrate_legacy_setting_keys(&db).await {
Ok(0) => {}
Ok(n) => tracing::info!(
target: "lumotia_startup",
rows_renamed = n,
elapsed_ms = t_keys.elapsed().as_millis(),
"renamed legacy magnotia_* settings keys to lumotia_*"
),
Err(e) => tracing::warn!(
target: "lumotia_startup",
error = %e,
"settings-key migration failed — continuing"
),
}
// Prune old `error_log` rows so the table doesn't grow unbounded
// across months of dogfooding. Best-effort — a prune failure is
// not worth blocking startup over.
@@ -247,7 +293,7 @@ pub fn run() {
// Load saved preferences for webview injection.
let t1 = Instant::now();
let prefs_json = get_setting(&db, "magnotia_preferences").await.unwrap_or(None);
let prefs_json = get_setting(&db, "lumotia_preferences").await.unwrap_or(None);
tracing::info!(target: "lumotia_startup", elapsed_ms = t1.elapsed().as_millis(), "preferences load complete");
let init_script = build_preferences_script(prefs_json);