Tasks
Na tej stronie
Przegląd komend
Dział zatytułowany „Przegląd komend”| Komenda | Opis | Typ |
|---|---|---|
list_tasks | Pobiera zadania (filtrowalne) | query |
create_task | Tworzy pojedyncze zadanie | write |
bulk_create_tasks | Tworzy wiele zadań | write |
update_task | Aktualizuje zadanie (status/priority/assignments/tags) | write |
delete_task | Usuwa zadanie | write |
unified_ai_generate_tasks | Generuje sugestie AI dla wizyty | write |
unified_ai_list_task_suggestions | Lista sugestii AI | query |
unified_ai_accept_task_suggestions | Akceptuje sugestie AI → tworzy zadania | write |
unified_ai_dismiss_task_suggestions | Odrzuca sugestie AI | write |
Task Data Model
Dział zatytułowany „Task Data Model”erDiagram TASK { string task_id PK string user_id FK string visit_id FK "Opcjonalnie" string patient_id FK "Opcjonalnie"
string title text description string priority "low, medium, high" string status "active, completed"
string task_type "manual | follow_up | general | ... (dowolny string)" string source "user | ai | system" string[] tags json metadata float confidence string content_hash "deduplikacja dla wizyty"
timestamp created_at timestamp updated_at timestamp resolved_at "ustawiane gdy status=completed" }
USER ||--o{ TASK : "assigned_to/created_by" VISIT ||--o{ TASK : "context (visit_id)" PATIENT ||--o{ TASK : "context (patient_id)"Task Types
Dział zatytułowany „Task Types”Vista rozróżnia dwa typy zadań:
flowchart LR subgraph TaskTypes["Typy zadań"] SYSTEM[🤖 System/AI Tasks] USER[👤 User Tasks] end
subgraph Sources["Źródła"] AI[AI Task Suggestions / System] MANUAL[Manual Creation (drawer/workspace)] end
AI --> SYSTEM MANUAL --> USER| Typ | Opis | Źródło |
|---|---|---|
system | Wygenerowane automatycznie (AI/automat) | AI suggestions, automaty |
user | Utworzone ręcznie przez użytkownika | Dashboard, Workspace |
Komendy CRUD
Dział zatytułowany „Komendy CRUD”list_tasks
Dział zatytułowany „list_tasks”Pobiera zadania użytkownika z opcjonalnymi filtrami:
interface Task { task_id: string; title: string; description: string | null; status: 'active' | 'completed'; task_type: string; priority: 'low' | 'medium' | 'high'; resolved_at: string | null; patient_id: string | null; visit_id: string | null; assigned_to: string | null; created_by: string | null; source: string; // user | ai | system tags?: string[]; metadata?: Record<string, unknown>; confidence?: number; content_hash?: string; created_at: string; updated_at: string;}
const tasks = await safeInvoke<Task[]>( 'list_tasks', withSessionPayload({ filter: { assigned_to?: string; created_by?: string; patient_id?: string; visit_id?: string; statuses?: ('active' | 'completed')[]; priorities?: ('low' | 'medium' | 'high')[]; task_types?: string[]; sources?: string[]; search?: string; include_resolved?: boolean; // false = filtruje completed limit?: number; // domyślnie 200, max 500 }, }));create_task
Dział zatytułowany „create_task”Tworzy nowe zadanie:
interface CreateTaskRequest { title: string; description?: string; priority?: 'low' | 'medium' | 'high'; // default: medium status?: 'active' | 'completed'; // completed ustawia resolved_at task_type?: string; // np. "general" patient_id?: string; visit_id?: string; assigned_to?: string; created_by?: string; source?: string; // user|ai|system tags?: string[]; metadata?: Record<string, unknown>;}
const task = await safeInvoke<Task>( 'create_task', withSessionPayload(request));update_task
Dział zatytułowany „update_task”interface UpdateTaskRequest { task_id: string; title?: string; description?: string; priority?: 'low' | 'medium' | 'high'; status?: 'active' | 'completed'; // completed ustawia resolved_at, inne czyszczą resolved_at task_type?: string; patient_id?: string; // '' lub undefined = bez zmian; '' => NULL visit_id?: string; // '' lub undefined = bez zmian; '' => NULL assigned_to?: string; metadata?: Record<string, unknown>; tags?: string[]; clear_tags?: boolean;}
const updated = await safeInvoke<Task>( 'update_task', withSessionPayload(request));delete_task
Dział zatytułowany „delete_task”await safeInvoke( 'delete_task', withSessionPayload({ task_id }));AI Task Suggestions
Dział zatytułowany „AI Task Suggestions”Po finalizacji wizyty, AI może automatycznie zasugerować follow-up tasks:
sequenceDiagram participant UI as VisitEditor participant Tauri as Tauri Backend participant AI as Unified AI participant DB as SQLite
UI->>Tauri: finalize_visit(visit_id) Tauri->>DB: UPDATE visits SET status = 'completed'
alt autoGenerateTasks enabled Tauri->>AI: unified_ai_generate_tasks(visit_id) AI->>AI: Analyze visit data (SOAP, transcript) AI-->>Tauri: TaskSuggestion[]
Tauri->>DB: INSERT INTO ai_task_suggestions
Tauri--)UI: Event: vista-tasks-refresh end
Tauri-->>UI: Successunified_ai_generate_tasks
Dział zatytułowany „unified_ai_generate_tasks”Generuje sugestie zadań na podstawie wizyty:
const result = await safeInvoke<GenerateTasksResponse>( 'unified_ai_generate_tasks', withSessionPayload({ visit_id }));
interface GenerateTasksResponse { success: boolean; suggestions: TaskSuggestion[]; reused: boolean; // true jeśli użyto wcześniejszych}
interface TaskSuggestion { suggestion_id: string; visit_id: string; title: string; description?: string; priority: 'low' | 'medium' | 'high'; suggested_due_date?: string; rationale?: string; status: 'pending' | 'accepted' | 'dismissed';}unified_ai_list_task_suggestions
Dział zatytułowany „unified_ai_list_task_suggestions”Lista sugestii AI dla wizyty:
// Frontend (src/hooks/tasks/useAiTaskSuggestions.ts)const suggestions = await safeInvoke<TaskSuggestion[]>( 'unified_ai_list_task_suggestions', withSessionPayload({ visit_id }));
// Tylko pending suggestions (nie accepted/dismissed)unified_ai_accept_task_suggestions
Dział zatytułowany „unified_ai_accept_task_suggestions”Akceptuje sugestie i tworzy z nich prawdziwe zadania:
// Frontendconst result = await safeInvoke<AcceptResult>( 'unified_ai_accept_task_suggestions', withSessionPayload({ suggestion_ids: ['sugg-1', 'sugg-2'] }));
interface AcceptResult { accepted_count: number; created_tasks: Task[];}
// Po akceptacji:// 1. suggestion.status = 'accepted'// 2. Tworzone są prawdziwe Task z task_type = 'system', source = 'ai'// 3. Operacja odbywa się w transakcji (SQLite) żeby uniknąć "database is locked"// 4. Event 'vista-tasks-refresh'unified_ai_dismiss_task_suggestions
Dział zatytułowany „unified_ai_dismiss_task_suggestions”Odrzuca sugestie (nie tworzy zadań):
await safeInvoke( 'unified_ai_dismiss_task_suggestions', withSessionPayload({ suggestion_ids: ['sugg-3'] }));
// suggestion.status = 'dismissed'// Nie pojawi się ponownie w liścieWorkspace Integration
Dział zatytułowany „Workspace Integration”Workspace ma dedykowaną zakładkę “Reminders” dla zadań:
flowchart TB subgraph Workspace["WorkspaceView"] TABS[Tabs: Drafts | Transcripts | Saved | Reminders] end
subgraph Reminders["Reminders Tab"] PINNED[📌 Pinned Tasks] USER_TASKS[👤 User Tasks] AI_SUGG[🤖 AI Suggestions] end
TABS --> Reminders
AI_SUGG -->|Accept| USER_TASKS AI_SUGG -->|Dismiss| HIDDEN[Hidden]useWorkspaceTasks Hook
Dział zatytułowany „useWorkspaceTasks Hook”const { tasks, pinnedTasks, aiSuggestions, loading,
createTask, updateTask, deleteTask, toggleComplete, pinTask, unpinTask,
acceptAiSuggestions, dismissAiSuggestions, refreshTasks,} = useWorkspaceTasks(visitId);Task Preferences
Dział zatytułowany „Task Preferences”Użytkownik może skonfigurować zachowanie AI tasks w preferencjach:
// UserPreferencesinterface TaskPreferences { tasks_panel_mode: 'manual' | 'auto' | 'off'; auto_generate_tasks: boolean;}
// manual: AI generuje sugestie, user musi zaakceptować// auto: AI generuje i automatycznie akceptuje (tworzy zadania)// off: AI nie generuje sugestiiTauri Events
Dział zatytułowany „Tauri Events”| Event | Payload | Kiedy |
|---|---|---|
vista-tasks-refresh | - | Po zmianach w zadaniach |
task-created | { task_id } | Po utworzeniu |
task-updated | { task_id } | Po aktualizacji |
task-deleted | { task_id } | Po usunięciu |
ai-suggestions-generated | { visit_id, count } | Po wygenerowaniu sugestii AI |
// NasłuchiwanieuseEffect(() => { const unlisten = window.addEventListener('vista-tasks-refresh', () => { refreshTasks(); });
return () => window.removeEventListener('vista-tasks-refresh', unlisten);}, []);Error Codes
Dział zatytułowany „Error Codes”| Kod | Opis | Rozwiązanie |
|---|---|---|
task_not_found | Zadanie nie istnieje | Sprawdź ID |
visit_not_found | Wizyta nie istnieje (dla AI tasks) | Sprawdź visit_id |
ai_generation_failed | Błąd generowania sugestii AI | Sprawdź dostępność AI |
suggestion_already_processed | Sugestia już zaakceptowana/odrzucona | Refresh listy |
invalid_priority | Nieprawidłowy priorytet | Użyj: low, medium, high |
API Contracts & Payloads
Dział zatytułowany „API Contracts & Payloads”Jawne kontrakty pomiędzy frontendem (React/TS) a komendami Tauri.
Task Model (Response)
Dział zatytułowany „Task Model (Response)”Odpowiedź z list_tasks, create_task, update_task dekodowana przez decodeTask:
interface Task { task_id: string; // globalny identyfikator (task_<uuid>) title: string; description: string | null; status: 'active' | 'completed'; task_type: string; // general, follow-up, ... priority: 'low' | 'medium' | 'high'; resolved_at: string | null; patient_id: string | null; visit_id: string | null; assigned_to: string | null; created_by: string | null; source: string; // user, ai, assistant tags: string[] | undefined; metadata: Record<string, unknown> | undefined; confidence: number | undefined; content_hash: string | undefined; created_at: string; // ISO timestamp updated_at: string;}Aliasowanie (Front → Backend)
Dział zatytułowany „Aliasowanie (Front → Backend)”Normalizacja w tasksService.ts:
| Pole | Wartość UI | Wysyłane do Tauri |
|---|---|---|
status | 'active' | 'active' |
'completed' | 'completed' | |
'pending', 'in_progress', 'snoozed', 'cancelled' | 'active' | |
priority | 'urgent' | 'high' |
'normal' | 'low' | |
'high', 'medium', 'low' | bez zmian |
create_task Payload
Dział zatytułowany „create_task Payload”{ "command": { "title": "Sprawdź wyniki badań", "description": "Zobacz panel krwi Mruczka", "status": "active", "priority": "medium", "task_type": "general", "patient_id": "pat_123", "visit_id": "visit_456", "source": "user", "tags": ["lab"], "metadata": { "visit_reason": "kontrola" } }}bulk_create_tasks Payload
Dział zatytułowany „bulk_create_tasks Payload”{ "tasks": [ { /* CreateTaskCommand */ }, { /* CreateTaskCommand */ } ]}list_tasks Filter
Dział zatytułowany „list_tasks Filter”{ "filter": { "assigned_to": "user_001", "statuses": ["active"], "priorities": ["high", "medium"], "sources": ["user", "ai"], "include_resolved": false, "limit": 200 }}Sortowanie: priority DESC, created_at DESC. Default limit: 200, max: 500.
update_task Payload
Dział zatytułowany „update_task Payload”{ "command": { "task_id": "task_abcd", "title": "Sprawdź wyniki badań", "priority": "high", "status": "completed", "metadata": { "completed_by": "user_001" }, "tags": ["lab", "done"] }}Jeśli status = completed, backend ustawia resolved_at. Pusty patient_id/visit_id = NULL.
delete_task Payload
Dział zatytułowany „delete_task Payload”{ "command": { "task_id": "task_abcd" }}Response: void (błąd jeśli nie istnieje).
Implementation Notes
Dział zatytułowany „Implementation Notes”- Status i priorytety są walidowane po stronie Tauri:
status ∈ {active, completed},priority ∈ {low, medium, high}. Inne wartości są odrzucane. update_taskz pustympatient_id/visit_idczyści powiązania (NULL).content_hashużywany do deduplikacji tytułów w kontekście wizyty (AI suggestions).- Operacje AI (generate/accept) pracują w transakcjach, aby uniknąć błędu
database is locked. - Brak pin/unpin w backendzie (UI zarządza widocznością lokalnie).
Powiązane dokumenty
Dział zatytułowany „Powiązane dokumenty”- Visits Commands - Finalizacja wizyt generuje AI tasks
- AI Commands - UnifiedAI API
- Settings Commands - Task preferences
- Dashboard - My Day section