| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "time" |
| 6 | ) |
| 7 | |
| 8 | type manualCreationDiagnosticReport struct { |
| 9 | Version string `json:"version"` |
| 10 | Commit string `json:"commit"` |
| 11 | ExportedAt string `json:"exportedAt"` |
| 12 | Tasks []manualCreationDiagnostic `json:"tasks"` |
| 13 | Events []manualCreationDiagnostic `json:"events"` |
| 14 | } |
| 15 | |
| 16 | func (a *App) manualCreationDiagnosticReport() manualCreationDiagnosticReport { |
| 17 | report := manualCreationDiagnosticReport{Version: version, Commit: buildCommit(), ExportedAt: time.Now().UTC().Format(time.RFC3339Nano), |
| 18 | Tasks: a.manualCreationDiagnostics(), Events: []manualCreationDiagnostic{}} |
| 19 | a.manualCreationMu.Lock() |
| 20 | m := a.manualCreations |
| 21 | a.manualCreationMu.Unlock() |
| 22 | if m != nil { |
| 23 | m.mu.Lock() |
| 24 | report.Events = append(report.Events, m.events...) |
| 25 | m.mu.Unlock() |
| 26 | } |
| 27 | return report |
| 28 | } |
| 29 | |
| 30 | // ExportManualCreationDiagnostics exports only allowlisted lifecycle metadata. |
| 31 | // It never reads chat content, configuration, attachments, or raw service logs. |
| 32 | func (a *App) ExportManualCreationDiagnostics() (string, error) { |
| 33 | payload, err := json.MarshalIndent(a.manualCreationDiagnosticReport(), "", " ") |
| 34 | if err != nil { |
| 35 | return "", err |
| 36 | } |
| 37 | path, err := a.PickExportFile("reasonix-creation-diagnostics-"+time.Now().Format("20060102-150405")+".json", "application/json") |
| 38 | if err != nil || path == "" { |
| 39 | return path, err |
| 40 | } |
| 41 | return path, a.SaveExportFile(path, string(payload), false) |
| 42 | } |
| 43 |