feat(storage): B2b — settings/profile schema + templates SQLite persistence

Settings: 8 new fields (lastLaunchAt, reentryFreshStartUntil,
lastActiveProfileId, microStepGranularity, nudgeMode, nudgeDigestTimes,
sparklineRangeDays, energyLabels) with sane defaults; nudgesEnabled
auto-maps to nudgeMode on first load (true→immediate, false→off).

Profile: optional energyLabelsOverride field on the localStorage
Profile shape — when present, overrides the global energyLabels;
absent/null falls through to settings.energyLabels via the new
resolveEnergyLabels helper.

Templates: migration v17 adds the templates table (id PK, name,
sections JSON, created_at, updated_at). 5 storage CRUD functions
plus import_templates with idempotent duplicate-id handling. 5 Tauri
commands (list/create/update/delete/import) wired and registered.
Frontend store rewired to read from SQLite via list_templates_cmd;
one-time migration imports kon_templates localStorage and clears it
on success. Fresh installs only seed the new {Meeting notes, Daily
check-in} defaults. Existing user templates survive the migration
verbatim.

Test coverage: 5 new Rust tests (CRUD, import idempotency, atomic
failure, updated_at bump, missing-id delete is no-op).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-26 19:16:31 +01:00
parent 0111fc9e08
commit e4cbf62a20
10 changed files with 943 additions and 37 deletions

View File

@@ -9,19 +9,21 @@ pub const DEFAULT_PROFILE_ID: &str = "00000000-0000-0000-0000-000000000001";
pub use database::{
add_profile_term, archive_inbox_older_than, archive_task,
complete_subtask_and_check_parent, complete_task, count_transcripts,
create_profile, create_task_list, delete_implementation_rule, delete_profile,
delete_profile_term, delete_task, delete_task_list, delete_transcript,
get_implementation_rule, get_profile, get_setting, get_task_by_id, get_transcript,
import_task_lists, init, init_readonly, insert_implementation_rule, insert_subtask,
insert_task, insert_transcript, list_archived_tasks, list_feedback_examples,
create_profile, create_task_list, create_template, delete_implementation_rule,
delete_profile, delete_profile_term, delete_task, delete_task_list,
delete_template, delete_transcript, get_implementation_rule, get_profile,
get_setting, get_task_by_id, get_transcript, import_task_lists, import_templates,
init, init_readonly, insert_implementation_rule, insert_subtask, insert_task,
insert_transcript, list_archived_tasks, list_feedback_examples,
list_implementation_rules, list_profile_terms, list_profiles, list_recent_completions,
list_recent_errors, list_subtasks, list_task_lists, list_tasks, list_transcripts,
list_transcripts_paged, log_error, mark_implementation_rule_fired, prune_error_log,
record_feedback, search_transcripts, set_implementation_rule_enabled, set_setting,
set_task_energy, unarchive_task, uncomplete_task, update_profile, update_task,
update_task_list, update_transcript, update_transcript_meta, DailyCompletionCount,
ErrorLogRow, FeedbackRow, FeedbackTargetType, ImplementationRuleRow, ImportSummary,
InsertTranscriptParams, ProfileRow, ProfileTermRow, RecordFeedbackParams, TaskListRow,
TaskRow, TranscriptRow,
list_recent_errors, list_subtasks, list_task_lists, list_tasks, list_templates,
list_transcripts, list_transcripts_paged, log_error, mark_implementation_rule_fired,
prune_error_log, record_feedback, search_transcripts, set_implementation_rule_enabled,
set_setting, set_task_energy, unarchive_task, uncomplete_task, update_profile,
update_task, update_task_list, update_template, update_transcript,
update_transcript_meta, DailyCompletionCount, ErrorLogRow, FeedbackRow,
FeedbackTargetType, ImplementationRuleRow, ImportSummary, InsertTranscriptParams,
ProfileRow, ProfileTermRow, RecordFeedbackParams, TaskListRow, TaskRow, TemplateRow,
TranscriptRow,
};
pub use file_storage::{app_data_dir, crashes_dir, database_path, logs_dir, recordings_dir};