fix: resolve 6 remaining defects (P2-18, P2-21, P3-04, P3-05, P3-06, P3-02)
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

- P2-18: TOTP QR code local generation via qrcode lib (no external service)
- P2-21: Suspend foreign LLM providers (OpenAI/Anthropic/Gemini) for early stage
- P3-04: get_progress() now calculates actual percentage from completed/total steps
- P3-05: saveSaaSSession calls now have .catch() error logging
- P3-06: SaaS relay chatStream passes session_key/agent_id to backend
- P3-02: Whiteboard unification plan document created

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-04-06 09:52:28 +08:00
parent d3da7d4dbb
commit 828be3cc9e
13 changed files with 414 additions and 58 deletions

View File

@@ -86,6 +86,7 @@ impl PipelineExecutor {
let run_id = run_id.to_string();
// Create run record
let total_steps = pipeline.spec.steps.len();
let run = PipelineRun {
id: run_id.clone(),
pipeline_id: pipeline_id.clone(),
@@ -95,6 +96,7 @@ impl PipelineExecutor {
step_results: HashMap::new(),
outputs: None,
error: None,
total_steps,
started_at: Utc::now(),
ended_at: None,
};
@@ -466,12 +468,26 @@ impl PipelineExecutor {
pub async fn get_progress(&self, run_id: &str) -> Option<PipelineProgress> {
let run = self.runs.read().await.get(run_id)?.clone();
let (current_step, percentage) = if run.step_results.is_empty() {
("starting".to_string(), 0)
} else if let Some(step) = &run.current_step {
(step.clone(), 50)
} else {
let (current_step, percentage) = if run.total_steps == 0 {
// Empty pipeline or unknown total
match run.status {
RunStatus::Completed => ("completed".to_string(), 100),
_ => ("starting".to_string(), 0),
}
} else if run.status == RunStatus::Completed {
("completed".to_string(), 100)
} else if let Some(step) = &run.current_step {
// P3-04: Calculate actual percentage from completed steps
let completed = run.step_results.len();
let pct = ((completed as f64 / run.total_steps as f64) * 100.0).min(99.0) as u8;
(step.clone(), pct)
} else if run.step_results.is_empty() {
("starting".to_string(), 0)
} else {
// Not running, not completed (failed/cancelled)
let completed = run.step_results.len();
let pct = ((completed as f64 / run.total_steps as f64) * 100.0) as u8;
("stopped".to_string(), pct)
};
Some(PipelineProgress {

View File

@@ -465,6 +465,10 @@ pub struct PipelineRun {
/// Error message (if failed)
pub error: Option<String>,
/// Total number of steps (P3-04: for granular progress)
#[serde(default)]
pub total_steps: usize,
/// Start time
pub started_at: chrono::DateTime<chrono::Utc>,