tftsr-devops_investigation/docs/wiki/Architecture.md
Shaun Arman fdb4fc03b9 docs(architecture): add C4 diagrams, ADRs, and architecture overview
Comprehensive architecture documentation covering:

- docs/architecture/README.md: Full C4 model diagrams (system context,
  container, component), data flow sequences, security architecture,
  AI provider class diagram, CI/CD pipeline, and deployment diagrams.
  All diagrams use Mermaid for version-controlled diagram-as-code.

- docs/architecture/adrs/ADR-001: Tauri vs Electron decision rationale
- docs/architecture/adrs/ADR-002: SQLCipher encryption choices and
  cipher_page_size=16384 rationale for Apple Silicon
- docs/architecture/adrs/ADR-003: Provider trait + factory pattern
- docs/architecture/adrs/ADR-004: Regex + Aho-Corasick PII detection
- docs/architecture/adrs/ADR-005: Auto-generate encryption keys at
  runtime (documents the fix from PR #24)
- docs/architecture/adrs/ADR-006: Zustand state management rationale

- docs/wiki/Architecture.md: Updated module table (14 migrations, not
  10), corrected integrations description, updated startup sequence to
  reflect key auto-generation, added links to new ADR docs.

- README.md: Fixed stale database paths (tftsr → trcaa) and updated
  env var descriptions to reflect auto-generation behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 09:35:35 -05:00

232 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Architecture
## Overview
TFTSR uses a Tauri 2.x architecture: a Rust backend runs natively, and a React/TypeScript frontend runs in an embedded WebView. Communication between them happens exclusively via typed IPC (`invoke()`).
```
┌─────────────────────────────────────────┐
│ WebView (React) │
│ pages/ → stores/ → tauriCommands.ts │
└──────────────────┬──────────────────────┘
│ invoke() / IPC
┌──────────────────▼──────────────────────┐
│ Rust Backend (Tauri) │
│ commands/ → ai/ → pii/ → db/ → docs/ │
└─────────────────────────────────────────┘
│ │
SQLCipher reqwest
DB (AI APIs)
```
## Backend — Rust
**Entry point:** `src-tauri/src/lib.rs``run()` initialises tracing, opens the DB, registers Tauri plugins, and calls `generate_handler![]` with all IPC commands.
### Shared State
```rust
pub struct AppState {
pub db: Arc<Mutex<rusqlite::Connection>>,
pub settings: Arc<Mutex<AppSettings>>,
pub app_data_dir: PathBuf, // ~/.local/share/trcaa on Linux
pub integration_webviews: Arc<Mutex<HashMap<String, String>>>,
}
```
All command handlers receive `State<'_, AppState>` as a Tauri-injected parameter. The Mutex must be **released before any `.await`** — holding a `MutexGuard` across an await point is a compile error because `MutexGuard` is not `Send`.
### Module Layout
| Path | Responsibility |
|------|---------------|
| `lib.rs` | App entry, tracing init, DB setup, plugin registration, command handler list |
| `state.rs` | `AppState` struct |
| `commands/db.rs` | Issue CRUD, 5-Whys entries, timeline events |
| `commands/ai.rs` | `analyze_logs`, `chat_message`, `list_providers` |
| `commands/analysis.rs` | Log file upload, PII detection, redaction |
| `commands/docs.rs` | RCA and post-mortem generation, document export |
| `commands/system.rs` | Ollama management, hardware probe, settings, audit log |
| `commands/integrations.rs` | Confluence / ServiceNow / ADO — OAuth2, WebView auth, tool calling |
| `ai/provider.rs` | `Provider` trait + `create_provider()` factory |
| `pii/detector.rs` | Multi-pattern PII scanner with overlap resolution |
| `db/migrations.rs` | Versioned schema (14 migrations tracked in `_migrations` table) |
| `db/models.rs` | All DB types — see `IssueDetail` note below |
| `docs/rca.rs` + `docs/postmortem.rs` | Markdown template builders |
| `audit/log.rs` | `write_audit_event()` — called before every external send |
### Directory Structure
```
src-tauri/src/
├── lib.rs
├── main.rs
├── state.rs
├── ai/
│ ├── provider.rs # Provider trait + factory
│ ├── openai.rs
│ ├── anthropic.rs
│ ├── gemini.rs
│ ├── mistral.rs
│ └── ollama.rs
├── commands/
│ ├── db.rs
│ ├── ai.rs
│ ├── analysis.rs
│ ├── docs.rs
│ ├── system.rs
│ └── integrations.rs
├── pii/
│ ├── patterns.rs
│ ├── detector.rs
│ └── redactor.rs
├── db/
│ ├── connection.rs
│ ├── migrations.rs
│ └── models.rs
├── docs/
│ ├── rca.rs
│ ├── postmortem.rs
│ └── exporter.rs
├── audit/
│ └── log.rs
├── ollama/
│ ├── installer.rs
│ ├── manager.rs
│ ├── recommender.rs
│ └── hardware.rs
└── integrations/
├── confluence.rs
├── servicenow.rs
└── azuredevops.rs
```
## Frontend — React/TypeScript
**IPC layer:** All Tauri `invoke()` calls are in `src/lib/tauriCommands.ts`. Every command has a typed wrapper. This is the single source of truth for the frontend API surface.
### Stores (Zustand)
| Store | Persistence | Contents |
|-------|------------|----------|
| `sessionStore.ts` | Not persisted (ephemeral) | currentIssue, messages, piiSpans, approvedRedactions, whyLevel (05), loading state |
| `settingsStore.ts` | `localStorage` as `"tftsr-settings"` | AI providers, theme, Ollama URL, active provider |
| `historyStore.ts` | Not persisted (cache) | Past issues list, search query |
### Page Flow
```
NewIssue → createIssueCmd → startSession(detail.issue) → navigate /issue/:id/triage
LogUpload → uploadLogFileCmd → detectPiiCmd → applyRedactionsCmd
Triage → chatMessageCmd loop → auto-detect why levels 15
Resolution → getIssueCmd → mark 5-Whys steps done
RCA → generateRcaCmd → DocEditor → exportDocumentCmd
```
### Directory Structure
```
src/
├── main.tsx
├── App.tsx
├── components/
│ ├── ChatWindow.tsx
│ ├── TriageProgress.tsx
│ ├── PiiDiffViewer.tsx
│ ├── DocEditor.tsx
│ ├── HardwareReport.tsx
│ ├── ModelSelector.tsx
│ └── ui/index.tsx # Custom components (Card, Button, Input, etc.)
├── pages/
│ ├── Dashboard/
│ ├── NewIssue/
│ ├── LogUpload/
│ ├── Triage/
│ ├── Resolution/
│ ├── RCA/
│ ├── Postmortem/
│ ├── History/
│ └── Settings/
│ ├── AIProviders.tsx
│ ├── Ollama.tsx
│ ├── Integrations.tsx
│ └── Security.tsx
├── stores/
│ ├── sessionStore.ts
│ ├── settingsStore.ts
│ └── historyStore.ts
└── lib/
├── tauriCommands.ts
└── domainPrompts.ts
```
## Key Type: IssueDetail
`get_issue()` returns a **nested** struct, not flat. Always use `detail.issue.*`:
```rust
pub struct IssueDetail {
pub issue: Issue, // Base fields (title, severity, etc.)
pub log_files: Vec<LogFile>,
pub resolution_steps: Vec<ResolutionStep>, // 5-Whys entries
pub conversations: Vec<AiConversation>,
}
```
Use `detail.issue.title`, **not** `detail.title`.
## Application Startup Sequence
```
1. Initialize tracing (RUST_LOG controls level)
2. Determine data directory (state::get_app_data_dir() or TFTSR_DATA_DIR)
3. Auto-generate or load .dbkey / .enckey (mode 0600) — see ADR-005
4. Open / create SQLCipher encrypted database
- If plain SQLite detected (debug→release upgrade): auto-migrate + backup
5. Run DB migrations (14 schema versions)
6. Create AppState (db + settings + app_data_dir + integration_webviews)
7. Register Tauri plugins (stronghold, dialog, fs, shell, http)
8. Register all IPC command handlers via generate_handler![]
9. Start WebView with React app
```
## Architecture Documentation
Full architecture documentation with C4 diagrams, data flow diagrams, and Architecture Decision Records (ADRs) is available in [`docs/architecture/`](../architecture/README.md):
| Document | Contents |
|----------|----------|
| [Architecture Overview](../architecture/README.md) | C4 diagrams, data flows, security model |
| [ADR-001](../architecture/adrs/ADR-001-tauri-desktop-framework.md) | Why Tauri over Electron |
| [ADR-002](../architecture/adrs/ADR-002-sqlcipher-encrypted-database.md) | SQLCipher encryption choices |
| [ADR-003](../architecture/adrs/ADR-003-provider-trait-pattern.md) | AI provider trait design |
| [ADR-004](../architecture/adrs/ADR-004-pii-regex-aho-corasick.md) | PII detection implementation |
| [ADR-005](../architecture/adrs/ADR-005-auto-generate-encryption-keys.md) | Key auto-generation design |
| [ADR-006](../architecture/adrs/ADR-006-zustand-state-management.md) | Frontend state management |
## Data Flow
```
User Input
[New Issue] ──── UUID assigned, stored in DB
[Upload Log] ─── File read, SHA-256 hash computed, path stored
[Detect PII] ─── 13 regex patterns applied, overlaps resolved
[Review PII] ─── User approves/rejects each span
[Apply Redactions] ─ Text rewritten, audit event logged
[AI Chat] ──────── Domain system prompt injected
Redacted text sent to provider
Auto-detect why level from response
[5-Whys] ───────── Answers stored as resolution_steps
[Generate RCA] ─── Markdown from template + answers
[Export] ────────── MD or PDF to user-chosen directory
```