feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
use crate::db::models::IssueDetail;
|
|
|
|
|
|
2026-04-19 23:13:30 +00:00
|
|
|
pub fn format_event_type(event_type: &str) -> &str {
|
|
|
|
|
match event_type {
|
|
|
|
|
"triage_started" => "Triage Started",
|
|
|
|
|
"log_uploaded" => "Log File Uploaded",
|
|
|
|
|
"why_level_advanced" => "Why Level Advanced",
|
|
|
|
|
"root_cause_identified" => "Root Cause Identified",
|
|
|
|
|
"rca_generated" => "RCA Document Generated",
|
|
|
|
|
"postmortem_generated" => "Post-Mortem Generated",
|
|
|
|
|
"document_exported" => "Document Exported",
|
|
|
|
|
other => other,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn calculate_duration(start: &str, end: &str) -> String {
|
|
|
|
|
let fmt = "%Y-%m-%d %H:%M:%S UTC";
|
|
|
|
|
let start_dt = match chrono::NaiveDateTime::parse_from_str(start, fmt) {
|
|
|
|
|
Ok(dt) => dt,
|
|
|
|
|
Err(_) => return "N/A".to_string(),
|
|
|
|
|
};
|
|
|
|
|
let end_dt = match chrono::NaiveDateTime::parse_from_str(end, fmt) {
|
|
|
|
|
Ok(dt) => dt,
|
|
|
|
|
Err(_) => return "N/A".to_string(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let duration = end_dt.signed_duration_since(start_dt);
|
|
|
|
|
let total_minutes = duration.num_minutes();
|
|
|
|
|
if total_minutes < 0 {
|
|
|
|
|
return "N/A".to_string();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let days = total_minutes / (24 * 60);
|
|
|
|
|
let hours = (total_minutes % (24 * 60)) / 60;
|
|
|
|
|
let minutes = total_minutes % 60;
|
|
|
|
|
|
|
|
|
|
if days > 0 {
|
|
|
|
|
format!("{days}d {hours}h")
|
|
|
|
|
} else if hours > 0 {
|
|
|
|
|
format!("{hours}h {minutes}m")
|
|
|
|
|
} else {
|
|
|
|
|
format!("{minutes}m")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
pub fn generate_rca_markdown(detail: &IssueDetail) -> String {
|
|
|
|
|
let issue = &detail.issue;
|
|
|
|
|
|
|
|
|
|
let mut md = String::new();
|
|
|
|
|
|
2026-04-04 20:10:17 +00:00
|
|
|
md.push_str(&format!(
|
|
|
|
|
"# Root Cause Analysis: {title}\n\n",
|
|
|
|
|
title = issue.title
|
|
|
|
|
));
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
md.push_str("## Issue Summary\n\n");
|
|
|
|
|
md.push_str("| Field | Value |\n");
|
|
|
|
|
md.push_str("|-------|-------|\n");
|
2026-04-04 20:05:13 +00:00
|
|
|
md.push_str(&format!("| **Issue ID** | {id} |\n", id = issue.id));
|
2026-04-04 20:10:17 +00:00
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Category** | {category} |\n",
|
|
|
|
|
category = issue.category
|
|
|
|
|
));
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Status** | {status} |\n",
|
|
|
|
|
status = issue.status
|
|
|
|
|
));
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Severity** | {severity} |\n",
|
|
|
|
|
severity = issue.severity
|
|
|
|
|
));
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Source** | {source} |\n",
|
|
|
|
|
source = issue.source
|
|
|
|
|
));
|
2026-03-15 17:43:46 +00:00
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Assigned To** | {} |\n",
|
|
|
|
|
if issue.assigned_to.is_empty() {
|
|
|
|
|
"Unassigned"
|
|
|
|
|
} else {
|
|
|
|
|
&issue.assigned_to
|
|
|
|
|
}
|
|
|
|
|
));
|
2026-04-04 20:10:17 +00:00
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Created** | {created_at} |\n",
|
|
|
|
|
created_at = issue.created_at
|
|
|
|
|
));
|
2026-04-04 20:05:13 +00:00
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| **Last Updated** | {updated_at} |\n",
|
|
|
|
|
updated_at = issue.updated_at
|
|
|
|
|
));
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
if let Some(ref resolved) = issue.resolved_at {
|
2026-03-15 18:28:59 +00:00
|
|
|
md.push_str(&format!("| **Resolved** | {resolved} |\n"));
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
2026-03-15 18:10:26 +00:00
|
|
|
md.push('\n');
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
if !issue.description.is_empty() {
|
|
|
|
|
md.push_str("## Description\n\n");
|
|
|
|
|
md.push_str(&issue.description);
|
|
|
|
|
md.push_str("\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-19 23:13:30 +00:00
|
|
|
// Incident Timeline
|
|
|
|
|
md.push_str("## Incident Timeline\n\n");
|
|
|
|
|
if detail.timeline_events.is_empty() {
|
|
|
|
|
md.push_str("_No timeline events recorded._\n\n");
|
|
|
|
|
} else {
|
|
|
|
|
md.push_str("| Time (UTC) | Event | Description |\n");
|
|
|
|
|
md.push_str("|------------|-------|-------------|\n");
|
|
|
|
|
for event in &detail.timeline_events {
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| {} | {} | {} |\n",
|
|
|
|
|
event.created_at,
|
|
|
|
|
format_event_type(&event.event_type),
|
|
|
|
|
event.description
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
md.push('\n');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Incident Metrics
|
|
|
|
|
md.push_str("## Incident Metrics\n\n");
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"- **Total Events:** {}\n",
|
|
|
|
|
detail.timeline_events.len()
|
|
|
|
|
));
|
|
|
|
|
if detail.timeline_events.len() >= 2 {
|
|
|
|
|
let first = &detail.timeline_events[0].created_at;
|
|
|
|
|
let last = &detail.timeline_events[detail.timeline_events.len() - 1].created_at;
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"- **Incident Duration:** {}\n",
|
|
|
|
|
calculate_duration(first, last)
|
|
|
|
|
));
|
|
|
|
|
} else {
|
|
|
|
|
md.push_str("- **Incident Duration:** N/A\n");
|
|
|
|
|
}
|
|
|
|
|
let root_cause_event = detail
|
|
|
|
|
.timeline_events
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|e| e.event_type == "root_cause_identified");
|
|
|
|
|
if let (Some(first), Some(rc)) = (detail.timeline_events.first(), root_cause_event) {
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"- **Time to Root Cause:** {}\n",
|
|
|
|
|
calculate_duration(&first.created_at, &rc.created_at)
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
md.push('\n');
|
|
|
|
|
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
// 5 Whys Analysis
|
|
|
|
|
md.push_str("## 5 Whys Analysis\n\n");
|
|
|
|
|
if detail.resolution_steps.is_empty() {
|
|
|
|
|
md.push_str("_No 5-whys analysis has been performed yet._\n\n");
|
|
|
|
|
} else {
|
|
|
|
|
for step in &detail.resolution_steps {
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"### Why #{}: {}\n\n",
|
|
|
|
|
step.step_order, step.why_question
|
|
|
|
|
));
|
|
|
|
|
if !step.answer.is_empty() {
|
2026-04-04 20:05:13 +00:00
|
|
|
md.push_str(&format!("**Answer:** {answer}\n\n", answer = step.answer));
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
} else {
|
|
|
|
|
md.push_str("_Awaiting answer._\n\n");
|
|
|
|
|
}
|
|
|
|
|
if !step.evidence.is_empty() {
|
2026-04-04 20:10:17 +00:00
|
|
|
md.push_str(&format!(
|
|
|
|
|
"**Evidence:** {evidence}\n\n",
|
|
|
|
|
evidence = step.evidence
|
|
|
|
|
));
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Root Cause
|
|
|
|
|
md.push_str("## Root Cause\n\n");
|
|
|
|
|
if let Some(last_step) = detail.resolution_steps.last() {
|
|
|
|
|
if !last_step.answer.is_empty() {
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"Based on the 5-whys analysis, the root cause is:\n\n> {}\n\n",
|
|
|
|
|
last_step.answer
|
|
|
|
|
));
|
|
|
|
|
} else {
|
|
|
|
|
md.push_str(
|
|
|
|
|
"_The 5-whys analysis is incomplete. Complete it to identify the root cause._\n\n",
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
md.push_str("_Perform the 5-whys analysis to identify the root cause._\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Log Files
|
|
|
|
|
md.push_str("## Log Files Analyzed\n\n");
|
|
|
|
|
if detail.log_files.is_empty() {
|
|
|
|
|
md.push_str("_No log files attached._\n\n");
|
|
|
|
|
} else {
|
|
|
|
|
md.push_str("| File | Size | Redacted | Hash |\n");
|
|
|
|
|
md.push_str("|------|------|----------|------|\n");
|
|
|
|
|
for lf in &detail.log_files {
|
|
|
|
|
md.push_str(&format!(
|
|
|
|
|
"| {} | {} bytes | {} | {}... |\n",
|
|
|
|
|
lf.file_name,
|
|
|
|
|
lf.file_size,
|
|
|
|
|
if lf.redacted { "Yes" } else { "No" },
|
|
|
|
|
&lf.content_hash[..8.min(lf.content_hash.len())],
|
|
|
|
|
));
|
|
|
|
|
}
|
2026-03-15 18:10:26 +00:00
|
|
|
md.push('\n');
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Corrective Actions
|
|
|
|
|
md.push_str("## Corrective Actions\n\n");
|
|
|
|
|
md.push_str("### Immediate Actions\n\n");
|
|
|
|
|
md.push_str("- [ ] _Document immediate mitigations taken_\n\n");
|
|
|
|
|
md.push_str("### Long-Term Actions\n\n");
|
|
|
|
|
md.push_str("- [ ] _Document preventive measures_\n");
|
|
|
|
|
md.push_str("- [ ] _Document monitoring improvements_\n\n");
|
|
|
|
|
|
|
|
|
|
// Lessons Learned
|
|
|
|
|
md.push_str("## Lessons Learned\n\n");
|
|
|
|
|
md.push_str("- _What went well during the response?_\n");
|
|
|
|
|
md.push_str("- _What could be improved?_\n");
|
|
|
|
|
md.push_str("- _What processes need updating?_\n\n");
|
|
|
|
|
|
|
|
|
|
md.push_str("---\n\n");
|
|
|
|
|
md.push_str(&format!(
|
2026-04-04 20:35:58 +00:00
|
|
|
"_Generated by Troubleshooting and RCA Assistant on {}_\n",
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
chrono::Utc::now().format("%Y-%m-%d %H:%M UTC")
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
md
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
2026-04-19 23:13:30 +00:00
|
|
|
use crate::db::models::{Issue, IssueDetail, LogFile, ResolutionStep, TimelineEvent};
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
|
|
|
|
|
fn make_test_detail() -> IssueDetail {
|
|
|
|
|
IssueDetail {
|
|
|
|
|
issue: Issue {
|
|
|
|
|
id: "test-123".to_string(),
|
|
|
|
|
title: "Database connection timeout".to_string(),
|
|
|
|
|
description: "Users report 500 errors on login.".to_string(),
|
|
|
|
|
severity: "high".to_string(),
|
|
|
|
|
status: "investigating".to_string(),
|
|
|
|
|
category: "database".to_string(),
|
|
|
|
|
source: "manual".to_string(),
|
|
|
|
|
created_at: "2025-01-15 10:00:00".to_string(),
|
|
|
|
|
updated_at: "2025-01-15 12:00:00".to_string(),
|
|
|
|
|
resolved_at: None,
|
|
|
|
|
assigned_to: "oncall-eng".to_string(),
|
|
|
|
|
tags: "[]".to_string(),
|
|
|
|
|
},
|
|
|
|
|
log_files: vec![LogFile {
|
|
|
|
|
id: "lf-1".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
file_name: "app.log".to_string(),
|
|
|
|
|
file_path: "/tmp/app.log".to_string(),
|
|
|
|
|
file_size: 2048,
|
|
|
|
|
mime_type: "text/plain".to_string(),
|
|
|
|
|
content_hash: "abc123def456".to_string(),
|
|
|
|
|
uploaded_at: "2025-01-15 10:30:00".to_string(),
|
|
|
|
|
redacted: false,
|
|
|
|
|
}],
|
2026-04-09 01:03:34 +00:00
|
|
|
image_attachments: vec![],
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
resolution_steps: vec![
|
|
|
|
|
ResolutionStep {
|
|
|
|
|
id: "rs-1".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
step_order: 1,
|
|
|
|
|
why_question: "Why are users getting 500 errors?".to_string(),
|
|
|
|
|
answer: "The database connection pool is exhausted.".to_string(),
|
|
|
|
|
evidence: "Connection pool metrics show 100/100 used.".to_string(),
|
|
|
|
|
created_at: "2025-01-15 11:00:00".to_string(),
|
|
|
|
|
},
|
|
|
|
|
ResolutionStep {
|
|
|
|
|
id: "rs-2".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
step_order: 2,
|
|
|
|
|
why_question: "Why is the connection pool exhausted?".to_string(),
|
|
|
|
|
answer: "Queries are not being released after completion.".to_string(),
|
|
|
|
|
evidence: "".to_string(),
|
|
|
|
|
created_at: "2025-01-15 11:15:00".to_string(),
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
conversations: vec![],
|
2026-04-19 23:02:38 +00:00
|
|
|
timeline_events: vec![],
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_contains_title() {
|
|
|
|
|
let md = generate_rca_markdown(&make_test_detail());
|
|
|
|
|
assert!(md.contains("# Root Cause Analysis: Database connection timeout"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_contains_issue_summary_table() {
|
|
|
|
|
let md = generate_rca_markdown(&make_test_detail());
|
|
|
|
|
assert!(md.contains("| **Issue ID** | test-123 |"));
|
|
|
|
|
assert!(md.contains("| **Severity** | high |"));
|
|
|
|
|
assert!(md.contains("| **Assigned To** | oncall-eng |"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_contains_five_whys() {
|
|
|
|
|
let md = generate_rca_markdown(&make_test_detail());
|
|
|
|
|
assert!(md.contains("### Why #1: Why are users getting 500 errors?"));
|
|
|
|
|
assert!(md.contains("**Answer:** The database connection pool is exhausted."));
|
|
|
|
|
assert!(md.contains("**Evidence:** Connection pool metrics"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_contains_root_cause() {
|
|
|
|
|
let md = generate_rca_markdown(&make_test_detail());
|
|
|
|
|
assert!(md.contains("Queries are not being released after completion."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_contains_log_files() {
|
|
|
|
|
let md = generate_rca_markdown(&make_test_detail());
|
|
|
|
|
assert!(md.contains("app.log"));
|
|
|
|
|
assert!(md.contains("2048 bytes"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_empty_steps_shows_placeholder() {
|
|
|
|
|
let mut detail = make_test_detail();
|
|
|
|
|
detail.resolution_steps.clear();
|
|
|
|
|
let md = generate_rca_markdown(&detail);
|
|
|
|
|
assert!(md.contains("No 5-whys analysis has been performed yet."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_unassigned_shows_unassigned() {
|
|
|
|
|
let mut detail = make_test_detail();
|
|
|
|
|
detail.issue.assigned_to = String::new();
|
|
|
|
|
let md = generate_rca_markdown(&detail);
|
|
|
|
|
assert!(md.contains("Unassigned"));
|
|
|
|
|
}
|
2026-04-19 23:13:30 +00:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_timeline_section_with_events() {
|
|
|
|
|
let mut detail = make_test_detail();
|
|
|
|
|
detail.timeline_events = vec![
|
|
|
|
|
TimelineEvent {
|
|
|
|
|
id: "te-1".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
event_type: "triage_started".to_string(),
|
|
|
|
|
description: "Triage initiated by oncall".to_string(),
|
|
|
|
|
metadata: "{}".to_string(),
|
|
|
|
|
created_at: "2025-01-15 10:00:00 UTC".to_string(),
|
|
|
|
|
},
|
|
|
|
|
TimelineEvent {
|
|
|
|
|
id: "te-2".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
event_type: "log_uploaded".to_string(),
|
|
|
|
|
description: "app.log uploaded".to_string(),
|
|
|
|
|
metadata: "{}".to_string(),
|
|
|
|
|
created_at: "2025-01-15 10:30:00 UTC".to_string(),
|
|
|
|
|
},
|
|
|
|
|
TimelineEvent {
|
|
|
|
|
id: "te-3".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
event_type: "root_cause_identified".to_string(),
|
|
|
|
|
description: "Connection pool leak found".to_string(),
|
|
|
|
|
metadata: "{}".to_string(),
|
|
|
|
|
created_at: "2025-01-15 12:15:00 UTC".to_string(),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
let md = generate_rca_markdown(&detail);
|
|
|
|
|
assert!(md.contains("## Incident Timeline"));
|
|
|
|
|
assert!(md.contains("| Time (UTC) | Event | Description |"));
|
|
|
|
|
assert!(md
|
|
|
|
|
.contains("| 2025-01-15 10:00:00 UTC | Triage Started | Triage initiated by oncall |"));
|
|
|
|
|
assert!(md.contains("| 2025-01-15 10:30:00 UTC | Log File Uploaded | app.log uploaded |"));
|
|
|
|
|
assert!(md.contains(
|
|
|
|
|
"| 2025-01-15 12:15:00 UTC | Root Cause Identified | Connection pool leak found |"
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_timeline_section_empty() {
|
|
|
|
|
let detail = make_test_detail();
|
|
|
|
|
let md = generate_rca_markdown(&detail);
|
|
|
|
|
assert!(md.contains("## Incident Timeline"));
|
|
|
|
|
assert!(md.contains("_No timeline events recorded._"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_rca_metrics_section() {
|
|
|
|
|
let mut detail = make_test_detail();
|
|
|
|
|
detail.timeline_events = vec![
|
|
|
|
|
TimelineEvent {
|
|
|
|
|
id: "te-1".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
event_type: "triage_started".to_string(),
|
|
|
|
|
description: "Triage started".to_string(),
|
|
|
|
|
metadata: "{}".to_string(),
|
|
|
|
|
created_at: "2025-01-15 10:00:00 UTC".to_string(),
|
|
|
|
|
},
|
|
|
|
|
TimelineEvent {
|
|
|
|
|
id: "te-2".to_string(),
|
|
|
|
|
issue_id: "test-123".to_string(),
|
|
|
|
|
event_type: "root_cause_identified".to_string(),
|
|
|
|
|
description: "Root cause found".to_string(),
|
|
|
|
|
metadata: "{}".to_string(),
|
|
|
|
|
created_at: "2025-01-15 12:15:00 UTC".to_string(),
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
let md = generate_rca_markdown(&detail);
|
|
|
|
|
assert!(md.contains("## Incident Metrics"));
|
|
|
|
|
assert!(md.contains("**Total Events:** 2"));
|
|
|
|
|
assert!(md.contains("**Incident Duration:** 2h 15m"));
|
|
|
|
|
assert!(md.contains("**Time to Root Cause:** 2h 15m"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_calculate_duration_hours_minutes() {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
calculate_duration("2025-01-15 10:00:00 UTC", "2025-01-15 12:15:00 UTC"),
|
|
|
|
|
"2h 15m"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_calculate_duration_days() {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
calculate_duration("2025-01-15 10:00:00 UTC", "2025-01-18 11:00:00 UTC"),
|
|
|
|
|
"3d 1h"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_calculate_duration_minutes_only() {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
calculate_duration("2025-01-15 10:00:00 UTC", "2025-01-15 10:45:00 UTC"),
|
|
|
|
|
"45m"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_calculate_duration_invalid() {
|
|
|
|
|
assert_eq!(calculate_duration("bad-date", "also-bad"), "N/A");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_format_event_type_known() {
|
|
|
|
|
assert_eq!(format_event_type("triage_started"), "Triage Started");
|
|
|
|
|
assert_eq!(format_event_type("log_uploaded"), "Log File Uploaded");
|
|
|
|
|
assert_eq!(
|
|
|
|
|
format_event_type("why_level_advanced"),
|
|
|
|
|
"Why Level Advanced"
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
format_event_type("root_cause_identified"),
|
|
|
|
|
"Root Cause Identified"
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(format_event_type("rca_generated"), "RCA Document Generated");
|
|
|
|
|
assert_eq!(
|
|
|
|
|
format_event_type("postmortem_generated"),
|
|
|
|
|
"Post-Mortem Generated"
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(format_event_type("document_exported"), "Document Exported");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_format_event_type_unknown() {
|
|
|
|
|
assert_eq!(format_event_type("custom_event"), "custom_event");
|
|
|
|
|
assert_eq!(format_event_type(""), "");
|
|
|
|
|
}
|
feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.
Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)
Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)
DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload
Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 03:36:25 +00:00
|
|
|
}
|