Adds a new "procedural" tree type for linear step-by-step project workflows (domain controller setup, M365 onboarding, VPN config, etc). Includes intake form builder, two-panel step navigation, variable resolution, procedural exports, 3 seed templates, and UI rename from "Trees" to "Flows". Also archives 19 implemented plan docs and creates deferred features backlog. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.9 KiB
Phase C: Sensitive Data Redaction — Planning State
Status: In planning — awaiting UI complexity decision Spec:
docs/plans/2026-02-13-EXPORT-IMPROVEMENTS-SPEC.mdsection C1 Branch: Not yet created (will befeat/export-phase-c)
Open Question
How much UI complexity for the redaction feature?
The spec describes per-item highlighting and individual mask/unmask toggles, which requires replacing the textarea with a custom editor component. Three options:
-
Simple toggle (Recommended) — Server-side mask toggle in preview modal. "Mask Sensitive Data" checkbox re-fetches with redaction applied. User sees summary of what was found (e.g. "3 IPs, 2 emails masked"). Manual editing for fine-tuning. Keeps the existing textarea.
-
Highlighted preview — Replace textarea with a rich editor that highlights detected patterns in yellow. "Mask All" button replaces them. No per-item toggle.
-
Full spec (per-item toggle) — Rich editor with highlights + individual checkboxes per detected item. Most complex — requires custom editor component, match tracking, and state management for each item.
What's Already Decided
Backend Architecture
- New file:
backend/app/services/redaction_service.py - Redaction happens BEFORE generators (pre-process session copy)
redaction_mode: Literal["none", "mask"] = "none"added toSessionExportschema- Regex patterns: IPv4, IPv6, email, bearer tokens, API keys, UNC paths
- Hostname redaction: opt-in (MSP tickets legitimately need hostnames)
- Deep copy of session — original DB record never modified
- No migration needed
Integration Point
In backend/app/api/endpoints/sessions.py line 296 (after session fetch, before generator call):
if export_options.redaction_mode == "mask":
session = apply_redaction(session) # Returns sanitized copy
Regex Patterns (conservative — false positives > false negatives)
- IPv4:
\b(?:\d{1,3}\.){3}\d{1,3}\b→[IP REDACTED] - IPv6:
\b(?:[0-9a-fA-F]{1,4}:){2,7}[0-9a-fA-F]{1,4}\b→[IP REDACTED] - Email:
\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b→[EMAIL REDACTED] - Bearer tokens:
Bearer\s+[A-Za-z0-9._-]+→[TOKEN REDACTED] - API key patterns: Long hex/base64 strings (32+ chars) →
[TOKEN REDACTED] - UNC paths:
\\\\[\w.-]+\\[\w$.-]+→[UNC PATH REDACTED]
Files to Modify
Backend:
- Create:
backend/app/services/redaction_service.py - Modify:
backend/app/schemas/session.py(addredaction_modetoSessionExport) - Modify:
backend/app/api/endpoints/sessions.py(3-line integration)
Frontend:
- Modify:
frontend/src/types/session.ts(addredaction_modetoSessionExport) - Modify:
frontend/src/components/session/ExportPreviewModal.tsx(add toggle) - Modify:
frontend/src/pages/SessionDetailPage.tsx(wire redaction state)
Tests:
- Create or extend:
backend/tests/test_psa_export.py(addTestPhaseCclass)