tftsr-devops_investigation/docs/TICKET-attachment-db-storage-recall.md
Shaun Arman 093495a653
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 0s
Test / rust-clippy (pull_request) Failing after 1s
Test / rust-tests (pull_request) Failing after 0s
Test / frontend-typecheck (pull_request) Failing after 16s
Test / frontend-tests (pull_request) Failing after 18s
PR Review Automation / review (pull_request) Failing after 4m13s
feat: full copy from apollo_nxt-trcaa with complete sanitization
Complete backport of all features from apollo_nxt-trcaa repository:
- Three-tier shell execution safety system (Tier 1: auto, Tier 2: approve, Tier 3: deny)
- Ollama function calling with tool use support
- AI provider tool calling auto-detection
- kubectl binary bundling and management
- kubeconfig upload and context management
- Shell approval modal with real-time UI
- MCP protocol HTTP transport with custom headers
- Enhanced security audit logging
- Comprehensive test coverage (275+ tests)
- Updated CI/CD workflows for Gitea Actions
- Complete documentation (ADRs, wiki, release notes)

Sanitization applied to all files:
- Removed all MSI, Motorola, VNXT, Vesta references
- Replaced internal infrastructure references with TFTSR equivalents
- Updated all URLs and API endpoints
- Sanitized commit history references in documentation

Technical changes:
- New modules: shell/classifier, shell/executor, shell/kubectl, shell/kubeconfig
- Enhanced AI providers: ollama.rs, openai.rs with function calling
- New Tauri commands: shell execution, kubeconfig management, tool calling detection
- Database migrations: shell_execution_audit table
- Frontend: ShellApprovalModal, ShellExecution, KubeconfigManager pages
- CI/CD: kubectl bundling, multi-platform builds, Gitea Actions integration

Version: 1.0.8

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-05 14:12:43 -05:00

119 lines
6.3 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.

# Ticket: Attachment DB Storage & Cross-Incident Recall
**Branch:** `feature/attachment-db-storage-recall`
**Base:** `master`
---
## Description
Log file and image attachment records previously stored only metadata and filesystem paths, making content volatile — if the source file moved or was deleted, the attachment record became orphaned. There was also no mechanism to search or recall attachments across incidents.
This feature:
1. Stores **gzip-compressed** log text and **raw image bytes** directly in the database, making attachments fully self-contained and portable.
2. Surfaces a new **Attachments tab** on the History page for cross-incident search and recall.
3. Exposes content-retrieval commands so the AI chat context can reference log content from DB on demand, with no disk dependency.
---
## Acceptance Criteria
- [x] Uploading a log file stores gzip-compressed text in `log_files.content_compressed` (BLOB)
- [x] Uploading an image stores raw bytes in `image_attachments.image_data` (BLOB)
- [x] `get_log_file_content` returns decompressed text from DB; falls back to disk for pre-migration records
- [x] `get_image_attachment_data` returns base64 data URL from DB; falls back to disk for pre-migration records
- [x] `list_all_log_files` returns cross-incident log summaries with joined issue title, supports search and issueId filter
- [x] `list_all_image_attachments` returns cross-incident image summaries with joined issue title, supports search and issueId filter
- [x] History page shows two tabs: **Issues** (existing, unchanged) and **Attachments** (new)
- [x] Attachments tab: Log Files section with filename, incident link, date, size, type badge, View button
- [x] Attachments tab: Images section with 48px thumbnail, filename, incident link, date, View button
- [x] "View" on log file → modal showing decompressed plain text
- [x] "View" on image → modal showing full-size image
- [x] Existing records with NULL content fall back to disk read — no breakage for pre-migration data
- [x] All new DB changes tracked via migrations 020022 with idempotency guarantees
- [x] Wiki documentation updated: IPC-Commands.md and Database.md
---
## Work Implemented
### Database (`src-tauri/src/db/`)
| File | Change |
|---|---|
| `migrations.rs` | Migrations 020 (`content_compressed BLOB`), 021 (`image_data BLOB`), 022 (views `v_log_files_with_issue` + `v_image_attachments_with_issue`). Extended duplicate-column graceful handling for new ALTER TABLE migrations. |
| `models.rs` | Added `LogFileSummary` and `ImageAttachmentSummary` structs for lightweight cross-incident list views (no BLOB fields — content stays out of IPC). |
### Rust Backend (`src-tauri/src/commands/`)
| File | Change |
|---|---|
| `analysis.rs` | Private `compress_text` / `decompress_text` helpers (flate2/miniz_oxide — pure Rust, no system binary). Updated `upload_log_file` and `upload_log_file_by_content` INSERTs to store `content_compressed`. New commands: `get_log_file_content`, `list_all_log_files`. |
| `image.rs` | Updated `upload_image_attachment`, `upload_image_attachment_by_content`, `upload_paste_image` INSERTs to store `image_data`. New commands: `get_image_attachment_data`, `list_all_image_attachments`. |
| `lib.rs` | Registered all 4 new commands. |
### Dependencies (`src-tauri/Cargo.toml`)
- Added `flate2 = { version = "1", features = ["rust_backend"] }` — pure-Rust gzip, portable cross-platform.
### Frontend (`src/`)
| File | Change |
|---|---|
| `lib/tauriCommands.ts` | Added `LogFileSummary`, `ImageAttachmentSummary` interfaces and 4 typed command wrappers. |
| `stores/attachmentStore.ts` | New Zustand store: `loadAttachments`, `searchAttachments`, `setSearchQuery`. |
| `pages/History/index.tsx` | Added tab bar; extracted `IssuesTab` (existing content, unchanged); added `AttachmentsTab` with log/image tables, search, View modals, and lazy `ImageThumbnail` component. |
### Documentation (`docs/wiki/`)
| File | Change |
|---|---|
| `IPC-Commands.md` | Documented `get_log_file_content`, `list_all_log_files`, `get_image_attachment_data`, `list_all_image_attachments` with TypeScript signatures and interface shapes. Updated upload command notes. |
| `Database.md` | Updated migration count (18 → 22). Documented migrations 020, 021, 022 with SQL, rationale, and usage notes. |
---
## Testing Needed
### Automated (already passing)
| Suite | Count | Status |
|---|---|---|
| Rust unit tests (`cargo test`) | 226 | ✅ All pass |
| Frontend unit tests (`npm run test:run`) | 103 | ✅ All pass |
| TypeScript type check (`tsc --noEmit`) | — | ✅ Clean |
| Rust clippy (`clippy -- -D warnings`) | — | ✅ Zero warnings |
| Rust format (`fmt --check`) | — | ✅ Clean |
New tests added:
- `test_compress_decompress_roundtrip`, `test_compress_large_text_is_smaller`, `test_decompress_invalid_bytes_returns_error` (Rust, `analysis.rs`)
- `test_get_image_attachment_data_base64_format` (Rust, `image.rs`)
- `test_020_log_content_compressed_column`, `test_021_image_data_column`, `test_022_attachment_views_exist`, `test_022_views_join_issue_title`, `test_020_021_idempotent` (Rust, `migrations.rs`)
- 9 attachment store tests (`tests/unit/attachmentStore.test.ts`)
### Manual Smoke Testing Required
1. **Log upload → DB content storage**
- Create issue → upload `.log` file → inspect SQLite: `SELECT id, LENGTH(content_compressed) FROM log_files` — verify non-NULL non-zero value
2. **Content retrieval from DB**
- History → Attachments tab → Log Files → click "View" → confirm readable decompressed text appears in modal
3. **Fallback for pre-migration records**
- Manually `UPDATE log_files SET content_compressed = NULL WHERE id = '<id>'` → View should still load from disk path
4. **Image upload → DB byte storage**
- Upload image → `SELECT id, LENGTH(image_data) FROM image_attachments` — verify non-NULL
5. **Image display**
- History → Attachments tab → Images → thumbnails should render, View → full-size image modal
6. **Cross-incident search**
- Create 2+ issues with different log files → Attachments tab → search by partial filename → correct files appear
7. **Issue link navigation**
- Click incident title in Attachments tab → navigates to correct triage page
8. **Issue tab unchanged**
- Verify existing Issues tab retains all functionality (search, filter, sort, open, export buttons)