Visits
Na tej stronie
Przegląd komend
Dział zatytułowany „Przegląd komend”| Komenda | Opis | Typ |
|---|---|---|
create_visit | Tworzy nową wizytę | write |
get_visit | Pobiera wizytę po ID | query |
get_all_visits | Pobiera wszystkie wizyty | query |
get_recent_visits | Pobiera ostatnie N wizyt | query |
update_visit | Aktualizuje wizytę (SOAP, status) | write |
delete_visit | Usuwa wizytę | write |
finalize_visit | Finalizuje wizytę | write |
duplicate_visit | Duplikuje wizytę | write |
export_visits | Eksportuje wizyty | query |
import_visits | Importuje wizyty | write |
Visit Data Model
Dział zatytułowany „Visit Data Model”erDiagram VISIT { string visit_id PK string patient_id FK string user_id FK "Lekarz prowadzący" string clinic_id FK timestamp visit_date
string visit_type "consultation, follow-up, vaccination..." string visit_status "draft, in_progress, completed, cancelled"
text soap_subjective "S - Wywiad" text soap_objective "O - Badanie" text soap_assessment "A - Rozpoznanie" text soap_plan "P - Plan leczenia"
text internal_notes "Notatki wewnętrzne" text ai_sugestie "AI suggestions JSON"
text transcript "Transkrypcja" text raw_transcript "Raw transcript" text pending_transcript "Fragment w trakcie" string audio_source_url string audio_source_type "live, upload" string recording_id FK
string processing_status "idle, transcribing, generating" timestamp created_at timestamp updated_at timestamp finalized_at }
PATIENT ||--o{ VISIT : "has" USER ||--o{ VISIT : "conducts"Visit Status Flow
Dział zatytułowany „Visit Status Flow”stateDiagram-v2 [*] --> draft: Nowa wizyta
draft --> in_progress: Rozpoczęcie edycji draft --> cancelled: Anulowanie
in_progress --> draft: Autosave in_progress --> completed: Finalizacja
completed --> [*]: Zakończona cancelled --> [*]: Anulowana
note right of draft: Można edytować note right of in_progress: Autosave co 30s note right of completed: Tylko podglądVisit Lifecycle
Dział zatytułowany „Visit Lifecycle”sequenceDiagram participant User participant UI as VisitsHubView participant Editor as useVisitEditor participant Tauri as Tauri Backend participant DB as SQLite participant AI as Unified AI
User->>UI: Nowa wizyta UI->>Tauri: create_visit(patient_id, visit_type) Tauri->>DB: INSERT INTO visits DB-->>Tauri: visit_id Tauri-->>UI: Visit
Note over UI,Editor: Edycja wizyty
loop Autosave (30s) Editor->>Tauri: update_visit(changes) Tauri->>DB: UPDATE visits SET ... end
opt Transkrypcja audio User->>UI: Nagrywa/uploaduje audio UI->>Tauri: transcribe_and_save_to_visit Tauri->>AI: STT AI-->>Tauri: transcript Tauri->>DB: UPDATE visits SET transcript = ... end
opt AI SOAP User->>UI: Generate SOAP UI->>AI: unified_ai_generate_soap AI-->>UI: SOAP sections UI->>Tauri: update_visit(soap_*) end
User->>UI: Finalizuj UI->>Tauri: finalize_visit(visit_id) Tauri->>DB: UPDATE visits SET visit_status = 'completed'
opt Auto AI Tasks Tauri->>AI: unified_ai_generate_tasks AI-->>Tauri: task suggestions end
Tauri-->>UI: SuccessKomendy CRUD
Dział zatytułowany „Komendy CRUD”create_visit
Dział zatytułowany „create_visit”Tworzy nową wizytę:
// Frontend (src/services/visitService.ts)interface CreateVisitRequest { patient_id: string; visit_type?: string; // 'consultation', 'follow-up', 'vaccination', etc. visit_date?: string; // ISO date, default: now user_id?: string; // Lekarz, default: current user}
const visit = await safeInvoke<Visit>( 'create_visit', withSessionPayload({ visit_data: request }));
// Responseinterface Visit { visit_id: string; patient_id: string; user_id: string; visit_date: string; visit_type: string; visit_status: 'draft'; soap_subjective?: string; soap_objective?: string; soap_assessment?: string; soap_plan?: string; // ... pozostałe pola}get_visit
Dział zatytułowany „get_visit”Pobiera pojedynczą wizytę:
const visit = await safeInvoke<Visit | null>( 'get_visit', withSessionPayload({ visit_id }));get_all_visits / get_recent_visits
Dział zatytułowany „get_all_visits / get_recent_visits”// Wszystkie wizytyconst visits = await safeInvoke<Visit[]>( 'get_all_visits', withSessionPayload({}));
// Ostatnie N wizytconst recentVisits = await safeInvoke<Visit[]>( 'get_recent_visits', withSessionPayload({ limit: 50 }));update_visit
Dział zatytułowany „update_visit”Aktualizuje wizytę - używane przez autosave i manualne zapisy:
interface UpdateVisitRequest { visit_id: string; // Required
// SOAP sections soap_subjective?: string; soap_objective?: string; soap_assessment?: string; soap_plan?: string;
// Other fields visit_status?: 'draft' | 'in_progress' | 'completed' | 'cancelled'; visit_type?: string; internal_notes?: string; ai_sugestie?: string;
// Audio/transcript transcript?: string; raw_transcript?: string; audio_source_url?: string; audio_source_type?: 'live' | 'upload';}
const updated = await safeInvoke<Visit>( 'update_visit', withSessionPayload({ visit_data: request }));delete_visit
Dział zatytułowany „delete_visit”await safeInvoke( 'delete_visit', withSessionPayload({ visit_id }));
// Emituje event: visit-deletedfinalize_visit
Dział zatytułowany „finalize_visit”Finalizuje wizytę - blokuje dalszą edycję:
sequenceDiagram participant UI as VisitEditor participant Tauri as Tauri Backend participant DB as SQLite participant AI as AI Tasks
UI->>Tauri: finalize_visit(visit_id) Tauri->>DB: UPDATE visits SET visit_status = 'completed', finalized_at = NOW() DB-->>Tauri: OK
alt autoGenerateTasks enabled Tauri->>AI: unified_ai_generate_tasks(visit_id) AI-->>Tauri: TaskSuggestion[]
alt suggestions found Tauri--)UI: Event: vista-tasks-refresh end end
Tauri-->>UI: FinalizedVisit// Frontend (src/hooks/visits/useVisitEditor.ts)const finalized = await safeInvoke<Visit>( 'finalize_visit', withSessionPayload({ visit_id }));
// Po finalizacji:// 1. visit_status = 'completed'// 2. finalized_at = current timestamp// 3. Opcjonalnie: AI generuje task suggestions// 4. Event 'vista-tasks-refresh' dla UIduplicate_visit
Dział zatytułowany „duplicate_visit”Duplikuje wizytę (np. follow-up):
const duplicated = await safeInvoke<Visit>( 'duplicate_visit', withSessionPayload({ source_visit_id: originalVisitId, new_visit_date: '2025-01-15' // Opcjonalnie }));
// Kopiuje: patient_id, visit_type, SOAP sections// Resetuje: visit_status = 'draft', visit_date = new/now// Nie kopiuje: transcript, audio, finalized_atSOAP Notes
Dział zatytułowany „SOAP Notes”Struktura SOAP
Dział zatytułowany „Struktura SOAP”flowchart TB subgraph SOAP["SOAP Note"] S[S - Subjective<br/>Wywiad od właściciela] O[O - Objective<br/>Badanie kliniczne] A[A - Assessment<br/>Rozpoznanie] P[P - Plan<br/>Plan leczenia] end
S --> O --> A --> PPola w bazie
Dział zatytułowany „Pola w bazie”| Pole | Opis | Przykład |
|---|---|---|
soap_subjective | Wywiad - co zgłasza właściciel | ”Pies nie je od 2 dni, wymiotuje” |
soap_objective | Badanie - co stwierdził lekarz | ”Temp. 39.5°C, tkliwość brzucha” |
soap_assessment | Rozpoznanie | ”Podejrzenie gastroenteritis” |
soap_plan | Plan leczenia | ”Płyny IV, dieta lekkostrawna” |
AI SOAP Generation
Dział zatytułowany „AI SOAP Generation”// Frontend (src/hooks/visits/useSOAPGeneration.ts)const { generateSOAP, isGeneratingSOAP, progress } = useSOAPGeneration();
// Generowanie SOAP z transkrypcjiconst result = await generateSOAP( patientData, // Patient info for context visitData, // Current visit data visitId, onProgress, // Progress callback userId);
// result zawiera wygenerowane sekcje S/O/A/P// które są automatycznie zapisywane przez useVisitEditorTranskrypcja i Audio
Dział zatytułowany „Transkrypcja i Audio”Powiązane pola
Dział zatytułowany „Powiązane pola”| Pole | Opis |
|---|---|
transcript | Finalna transkrypcja |
raw_transcript | Surowa transkrypcja (przed cleanup) |
pending_transcript | Fragment w trakcie transkrypcji |
audio_source_url | Ścieżka do pliku audio |
audio_source_type | 'live' (nagranie) lub 'upload' |
recording_id | FK do tabeli recordings |
Integracja z audio
Dział zatytułowany „Integracja z audio”// Transkrypcja i zapis do wizytyawait safeInvoke( 'transcribe_and_save_to_visit', withSessionPayload({ file_path: audioPath, visit_id: visitId, source_type: 'live' // lub 'upload' }));
// Backend:// 1. Transkrybuje audio (STT)// 2. Zapisuje transcript do wizyty// 3. Emituje event: transcription_completedPending Transcript
Dział zatytułowany „Pending Transcript”Dla długich nagrań, transkrypcja może być stopniowa:
// Merge pending fragment z główną transkrypcjąawait safeInvoke( 'merge_pending_transcript', withSessionPayload({ visit_id }));
// Odrzuć pending fragmentawait safeInvoke( 'dismiss_pending_transcript', withSessionPayload({ visit_id }));Filtrowanie i sortowanie
Dział zatytułowany „Filtrowanie i sortowanie”Frontend obsługuje filtrowanie po stronie klienta:
interface VisitFilters { status?: 'draft' | 'in_progress' | 'completed' | 'cancelled'; visitType?: string; dateRange?: { start: Date; end: Date }; patientId?: string; userId?: string; // Lekarz hasTranscript?: boolean; hasAudio?: boolean;}
const filteredVisits = useMemo(() => { return visits.filter(visit => { if (filters.status && visit.visit_status !== filters.status) return false; if (filters.visitType && visit.visit_type !== filters.visitType) return false; if (filters.patientId && visit.patient_id !== filters.patientId) return false; // ... więcej filtrów return true; });}, [visits, filters]);Tauri Events
Dział zatytułowany „Tauri Events”| Event | Payload | Kiedy |
|---|---|---|
visit-created | { visit_id } | Po utworzeniu |
visit-updated | { visit_id } | Po aktualizacji |
visit-deleted | { visit_id } | Po usunięciu |
visit-finalized | { visit_id } | Po finalizacji |
transcription_completed | { visit_id } | Po zakończeniu STT |
vista-tasks-refresh | - | Po wygenerowaniu AI tasks |
useVisitEditor Hook
Dział zatytułowany „useVisitEditor Hook”Centralny hook do edycji wizyt:
const { // Stan visit, editedData, isDirty, isSaving, isGeneratingSOAP,
// Akcje setEditedData, saveVisit, finalize, generateSOAP, cancelGeneration,
// SOAP updateSOAPSection,
// Audio attachAudio, retryTranscription,} = useVisitEditor(visitId);
// AutosaveuseEffect(() => { if (isDirty) { const timer = setTimeout(() => saveVisit(), 30000); return () => clearTimeout(timer); }}, [isDirty, editedData]);Export / Import
Dział zatytułowany „Export / Import”export_visits
Dział zatytułowany „export_visits”const data = await safeInvoke<string>( 'export_visits', withSessionPayload({ format: 'json' }));
// Zapis do plikuawait saveFile(data, 'visits-export.json');import_visits
Dział zatytułowany „import_visits”const result = await safeInvoke<ImportResult>( 'import_visits', withSessionPayload({ format: 'json', data: fileContent }));Error Codes
Dział zatytułowany „Error Codes”| Kod | Opis | Rozwiązanie |
|---|---|---|
visit_not_found | Wizyta nie istnieje | Sprawdź ID |
visit_already_finalized | Wizyta już sfinalizowana | Utwórz duplikat |
patient_not_found | Pacjent nie istnieje | Sprawdź patient_id |
invalid_visit_status | Nieprawidłowy status | Sprawdź dozwolone wartości |
transcription_failed | Błąd transkrypcji | Sprawdź audio |
soap_generation_failed | Błąd generowania SOAP | Sprawdź transkrypcję |
Powiązane dokumenty
Dział zatytułowany „Powiązane dokumenty”- Patients Commands - Komendy pacjentów
- Audio Commands - Komendy audio
- AI Commands - Komendy AI (SOAP generation)
- Tasks Commands - Komendy zadań (AI suggestions)
- Database Schema - Schemat bazy