Przejdź do głównej zawartości

Settings Module

Ustawienia użytkownika i kliniki. ~25 plików, ~11k LOC.

Na tej stronie
graph TB
subgraph SettingsView["Settings View"]
SettingsTabs[SettingsTabsView]
end
subgraph UserSettings["User Settings"]
Profile[ProfileSettings]
Preferences[PreferencesSettings<br/>28k LOC]
Language[LanguageSettings]
Theme[PersonalizationSettings<br/>+ CustomThemeWizard]
Biometric[BiometricSettings]
Pin[PinSettings]
end
subgraph DataSettings["Data Settings"]
Privacy[PrivacySections<br/>17k LOC]
Database[DatabaseManagement<br/>11k LOC]
FileCleanup[FileCleanupSettings]
PDFCache[PDFCacheSettings]
ChatHistory[ChatHistorySettings]
end
subgraph AdminSettings["Admin Only"]
Clinic[ClinicSettings<br/>21k LOC]
Users[UserManagement]
Invitations[InvitationsPanel]
MCP[MCPSettings]
AITests[AITestsPanel<br/>19k LOC]
end
subgraph PreferencesData["Preferences Data Flow"]
Schema[UserPreferencesSchema<br/>Zod validation]
Service[userPreferences.ts]
Context[TaskPreferencesContext]
end
SettingsTabs --> UserSettings
SettingsTabs --> DataSettings
SettingsTabs --> AdminSettings
UserSettings --> PreferencesData
erDiagram
USER_PREFERENCES {
enum note_style "soap | narrative"
enum ai_precision_level "minimal | balanced | complete"
enum history_depth "brief | standard | full"
enum content_format "paragraph | bullets"
enum tone_of_voice "neutral | warm | professional | friendly | clinical"
int audio_retention_days "1-30, default 2"
}
USER_PREFERENCES {
enum practice_mode "solo | team | demo"
string workspace_mode
array integrations "string[]"
enum workday_style "planned | dynamic | balanced"
enum docs_style "detailed | quick | keypoints"
enum tech_profile "innovator | practical | conservative"
}
USER_PREFERENCES {
bool terms_accepted
bool privacy_accepted
bool microphone_permission
bool tts_enabled "text-to-speech"
enum tasks_panel_mode "manual | auto | off"
bool auto_generate_tasks
}
sequenceDiagram
participant User
participant UI as PreferencesSettings
participant Schema as UserPreferencesSchema
participant Service as userPreferences.ts
participant Rust as update_user_preferences_session
participant DB as user_preferences table
User->>UI: Change preference
UI->>Schema: validatePartialUserPreferences(data)
Schema-->>UI: Validated data
UI->>Service: updateUserPreferences(prefs)
Service->>Service: extractUserPreferences()
Service->>Service: toSnakeCaseDeep()
Service->>Rust: invoke('update_user_preferences_session')
Rust->>DB: UPDATE user_preferences SET ...
DB-->>Rust: OK
Rust-->>Service: Success
Service-->>UI: Done
UI->>User: Show confirmation
ComponentLOCDescription
PreferencesSettings28,773Main preferences panel
ClinicSettings20,839Clinic management (admin)
AITestsPanel19,403AI diagnostics (admin)
PrivacySections17,327GDPR/privacy settings
CustomThemeWizard13,400Theme customization
DatabaseManagement11,100DB admin tools
FileCleanupSettings8,810Storage cleanup
MCPSettings7,258MCP server config
FE FunctionRust CommandDescription
updateUserPreferences(prefs)update_user_preferences_sessionUpdate single/multiple prefs
batchUpdateUserPreferences(updates)update_user_preferences_sessionBatch updates
completeOnboarding(prefs)update_user_preferences_sessionFinalize onboarding
skipOnboarding()update_user_preferences_sessionSkip with defaults
PreferenceDefaultOptions
noteStylesoapsoap, narrative
aiPrecisionLevelbalancedminimal, balanced, complete
historyDepthstandardbrief, standard, full
contentFormatparagraphparagraph, bullets
toneOfVoiceneutralneutral, warm, professional, friendly, clinical
audioRetentionDays21-30
practiceModesolosolo, team, demo
workdayStylebalancedplanned, dynamic, balanced
docsStylequickdetailed, quick, keypoints
techProfilepracticalinnovator, practical, conservative
tasksPanelModemanualmanual, auto, off

Complete onboarding data flow:

Step 1: Welcome & Terms
↓ (termsAccepted, privacyAccepted)
Step 2: Practice Mode Selection
↓ (practiceMode: solo/team/demo)
Step 3: Workspace Configuration
↓ (workspaceMode, teamMembers)
Step 4: AI Precision Level
↓ (aiPrecisionLevel: minimal/balanced/complete)
Step 5: Tone of Voice
↓ (toneOfVoice: neutral/warm/professional)
Step 6: Documentation Style
↓ (docsStyle: detailed/quick/keypoints)
Step 7: Tech Profile
↓ (techProfile: innovator/practical/conservative)
Step 8: Template Preview
↓ (shows all selections with real examples)
FINISH: Batch Update
↓ (batchUpdateUserPreferencesSession)
Settings Applied & User Ready

Human-readable display (src/utils/preferenceLabels.ts):

export const PREFERENCE_LABELS = {
aiPrecisionLevel: {
minimal: 'Minimalna pomoc',
balanced: 'Zbalansowana',
complete: 'Pełna automatyzacja',
},
workdayStyle: {
planned: 'Spokojny, planowy',
dynamic: 'Dynamiczny, nagły',
balanced: 'Zbalansowany',
},
docsStyle: {
detailed: 'Pełne sekcje (strukturalnie)',
quick: 'Szybkie notowanie (akapitowo)',
keypoints: 'Tylko kluczowe punkty',
},
toneOfVoice: {
neutral: 'Neutralny',
warm: 'Ciepły',
professional: 'Profesjonalny',
friendly: 'Przyjazny',
clinical: 'Kliniczny',
},
techProfile: {
innovator: 'Innowator',
practical: 'Praktyk',
conservative: 'Konserwatysta',
},
practiceMode: {
solo: 'Praca samodzielna',
team: 'Praca w zespole',
demo: 'Tryb demonstracyjny',
},
};

Case conversion system:

// Automatic camelCase ↔ snake_case conversion
export function toDBFormat(preferences: Partial<UserPreferences>) {
return toSnakeCaseDeep(preferences);
}
// Frontend preferences (camelCase)
{
aiPrecisionLevel: 'balanced',
workdayStyle: 'planned',
docsStyle: 'detailed'
}
// ↓ toSnakeCaseDeep() ↓
// Backend payload (snake_case)
{
ai_precision_level: 'balanced',
workday_style: 'planned',
docs_style: 'detailed'
}

src/schemas/userPreferences.ts
export const UserPreferencesSchema = z.object({
// Core medical preferences
noteStyle: z.enum(['soap', 'narrative']).default('soap'),
aiPrecisionLevel: z.enum(['minimal', 'balanced', 'complete']).default('balanced'),
historyDepth: z.enum(['brief', 'standard', 'full']).default('standard'),
contentFormat: z.enum(['paragraph', 'bullets']).default('paragraph'),
toneOfVoice: z.enum(['neutral', 'warm', 'professional', 'friendly', 'clinical']).default('neutral'),
audioRetentionDays: z.number().min(1).max(365).default(14),
// Workflow preferences
practiceMode: z.enum(['solo', 'team', 'demo']).default('solo'),
workdayStyle: z.enum(['planned', 'dynamic', 'balanced']).default('balanced'),
docsStyle: z.enum(['detailed', 'quick', 'keypoints']).default('quick'),
techProfile: z.enum(['innovator', 'practical', 'conservative']).default('practical'),
// System preferences
termsAccepted: z.boolean().default(false),
privacyAccepted: z.boolean().default(false),
microphonePermission: z.boolean().optional(),
workspaceMode: z.string().optional(),
integrations: z.array(z.string()).optional(),
});

MetricValue
Files~25
LOC~11,100
Tauri Commands12
Key HookusePreferences

graph TB
subgraph UI["Settings UI"]
SettingsTabs[SettingsTabsView]
ProfileTab[ProfileSettings]
PrefsTab[PreferencesSettings]
ClinicTab[ClinicSettings]
SecurityTab[SecuritySettings]
end
subgraph Providers["State Providers"]
SettingsProvider[SettingsProvider]
AuthContext[AuthContext]
end
subgraph Hooks["Hooks Layer"]
usePrefs[usePreferences]
useClinic[useClinicSettings]
useSecurity[useSecuritySettings]
end
subgraph Backend["Tauri Commands"]
GetPrefs[get_user_preferences]
SavePrefs[save_user_preferences]
GetClinic[get_clinic_settings]
SaveClinic[save_clinic_settings]
end
SettingsTabs --> ProfileTab
SettingsTabs --> PrefsTab
SettingsTabs --> ClinicTab
SettingsTabs --> SecurityTab
ProfileTab --> AuthContext
PrefsTab --> usePrefs
ClinicTab --> useClinic
SecurityTab --> useSecurity
usePrefs --> GetPrefs
usePrefs --> SavePrefs
useClinic --> GetClinic
useClinic --> SaveClinic

System mapuje preferencje z onboardingu na czytelne etykiety:

PreferenceValuesEtykiety
noteStylesoap, narrativeSOAP, Narracyjny
aiPrecisionLevelminimal, balanced, completeMinimalny, Zbalansowany, Pełny
historyDepthbrief, standard, fullKrótka, Standardowa, Pełna
contentFormatparagraph, bulletsAkapity, Punkty
toneOfVoiceneutral, warm, professional, friendly, clinicalNeutralny, Ciepły, Profesjonalny, Przyjazny, Kliniczny
practiceModesolo, team, demoSolo, Zespół, Demo
workdayStyleplanned, dynamic, balancedPlanowany, Dynamiczny, Zbalansowany
docsStyledetailed, quick, keypointsSzczegółowy, Szybki, Kluczowe punkty
techProfileinnovator, practical, conservativeInnowator, Praktyk, Konserwatysta