Diagnose-Sichtbarkeit (Plan A):
- Job.step_started_at + last_heartbeat_at, Heartbeat-Task pingt alle 3 s
während laufender Mac-Calls
- Mac-Worker hält per X-Job-Id Header einen Log-Ringbuffer pro Job
(200 Zeilen, 1 h TTL); GET /api/jobs/{id}/log liefert ihn aus
- LXC-Endpoint GET /api/jobs/{id}/diag bündelt Job-Status, Stage-Sekunden,
Heartbeat-Alter und Mac-Worker-Log
- Frontend: Live-Timing im Status-Pill ("läuft seit Xs · letzter Ping vor Ys"),
klappbares Diagnose-Panel mit Mac-Log für FAILED + langlaufende Jobs
Robustheit (Plan B):
- MacClient: einmaliger Retry mit 3 s Backoff bei RemoteProtocolError /
ConnectError / ReadError für summarize/protocol/export
- Mac-Worker /api/preload heizt Ollama vor (keep_alive 30 m, num_predict 1);
Pipeline ruft Preload vor summarize, damit Modell-Reload nicht mitten
in der Generierung passiert (Hauptursache "Server disconnected")
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
35 lines
1.1 KiB
Python
35 lines
1.1 KiB
Python
from datetime import datetime, timezone
|
|
from typing import Optional
|
|
from sqlmodel import SQLModel, Field
|
|
|
|
|
|
class JobStatus:
|
|
QUEUED = "queued"
|
|
TRANSCRIBING = "transcribing"
|
|
SUMMARIZING = "summarizing"
|
|
PROTOCOLLING = "protocolling"
|
|
EXPORTING = "exporting"
|
|
DONE = "done"
|
|
FAILED = "failed"
|
|
|
|
|
|
class Job(SQLModel, table=True):
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
owner_id: Optional[int] = Field(default=None, foreign_key="user.id", index=True)
|
|
profile: str = Field(default="meeting")
|
|
filename: str
|
|
original_name: str
|
|
title: str = ""
|
|
status: str = JobStatus.QUEUED
|
|
progress: int = 0
|
|
error: str = ""
|
|
transcript_path: str = ""
|
|
summary_path: str = ""
|
|
protocol_path: str = ""
|
|
docx_path: str = ""
|
|
pdf_path: str = ""
|
|
step_started_at: Optional[datetime] = Field(default=None)
|
|
last_heartbeat_at: Optional[datetime] = Field(default=None)
|
|
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
|
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|