Server-side regex redaction masks IPs, emails, bearer/API tokens, and
UNC paths in exported session content. Redaction runs post-generation
and post-variable-resolution with fail-closed error handling. Frontend
gets a "Mask Sensitive Data" toggle in the export preview modal with
a summary of what was redacted. 24 unit tests passing, frontend build clean.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add next_steps to Session, SessionUpdate, SessionComplete, SessionExport types
- Add Next Steps textarea to SessionOutcomeModal
- Update TreeNavigationPage consumer callback for next_steps
- Display next_steps with whitespace-pre-wrap on SessionDetailPage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add copy-to-clipboard buttons on command blocks (action + custom step nodes)
- Add keyboard shortcuts modal (?) with option loading spinners and [Esc] hint
- Restyle session timer as a pill badge for better visibility
- Add prominent "Create Tree" CTA to MyTreesPage header and empty state
- Make breadcrumb items clickable to rewind navigation to any previous step
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Engineers can now paste command output during action steps. Output is
stored in the session decisions JSONB, displayed in session review,
included in all 4 export formats with command context, and preserved
in session-to-tree conversions.
- Collapsible "Paste Output" textarea on action nodes with commands
- 10,000 character limit with live character count
- Works on both built-in and custom action steps
- Preloads output when revisiting a step via Go Back
- All exports show commands run alongside captured output
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Revoke-and-recreate flow for both invite systems with email delivery
via Resend API. Includes account invite email template and audit logging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Migration 030: add email, assigned_plan, trial_duration_days, email_sent_at
to invite_codes with CHECK constraints
- Resend email integration (graceful degradation when API key not set)
- Invite codes now support plan assignment (free/pro/team) and trial duration (1-90 days)
- Registration applies invite code plan/trial to new subscription
- Auto-downgrade expired trials on authenticated access
- Enriched GET /admin/users/{id} with account, subscription, sessions, audit logs
- New endpoints: PUT /admin/users/{id}/subscription/plan and extend-trial
- Frontend: enhanced invite codes page with email, plan, trial fields
- Frontend: new user detail page at /admin/users/:userId
- Fixed API path drift: /invite-codes -> /invites
- 11 new backend tests, 416 total passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add session quick wins (#51-#55)
- Session timer showing elapsed time in header (#51)
- Tab keyboard shortcut to focus notes textarea (#52)
- Repeat Last Session button on tree library page (#53)
- Auto-recovery banner for incomplete sessions (#54)
- Copy individual step to clipboard on session detail (#55)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add missing delete button to table and list tree views
The onDeleteTree prop was accepted but never used in TreeTableView and
TreeListView. Now both views show a trash icon (permission-gated) matching
the existing grid view behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Replace all `from '@/api'` barrel imports with direct imports from
specific module files (e.g. `from '@/api/trees'`) across 20 files.
This enables better tree-shaking so each page only bundles the API
modules it actually uses.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TreeLibraryPage: split categories into a mount-only fetch so filter
changes only re-fetch trees (not categories every time)
- Add safeGetItem/safeSetItem/safeRemoveItem helpers in utils.ts to
prevent crashes in private browsing or when storage is unavailable
- Replace raw localStorage calls in ScratchpadSidebar, TreeNavigationPage,
TreeEditorPage, and treeEditorStore with safe wrappers
- Add aria-label to 20 icon-only buttons across 8 component files
for screen reader accessibility
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The page was making 1 API call per tree to fetch session stats, but the
backend sessions endpoint doesn't support tree_id filtering — so every
call returned identical data. Now fetches trees and sessions in parallel
(2 calls total), builds a lastUsed map client-side, and uses the existing
usage_count field from the tree list response for session counts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements the full dual-mode tree editor (Plan Phases 1-5):
Backend:
- JSONB↔Markdown bidirectional serializer/parser with mistune
- Markdown validator with line/column error reporting
- 3 API endpoints: export-markdown, import-markdown, validate-markdown
- Variable extraction/resolution service ([USER_INPUT], [VAR], [SAVE_AS])
- Session variables JSONB column (migration 028)
- 39 tree markdown tests + variable service tests (403 total passing)
Frontend:
- Monaco-based Code Mode with custom Monarch tokenizer and dark theme
- Autocomplete for @node_id refs, type values, variable names
- Debounced validation (800ms) with inline Monaco error markers
- Syntax help panel (absolute overlay, toggleable)
- Starter template for new trees with valid cross-references
- Bidirectional metadata sync (name/description/category/tags frontmatter)
- Synchronous tree→markdown serializer (fixes async race condition)
- Pre-save validation blocks save on broken refs or missing tree name
- Mode-aware undo/redo: Monaco native in Code Mode, throttled zundo in Flow Mode
- Variable prompt modal and frontend resolver for session navigation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migrate all 84 frontend files from the old themed/colored design to a
monochrome glass-morphism design system. Pure black backgrounds, white
text with opacity levels, glass-card components with backdrop-blur, and
functional color reserved for status indicators only.
Foundation: remap CSS variables to monochrome, simplify Tailwind config,
remove theme toggle, convert brand logo/wordmark to white. Pages: all
14 pages updated. Components: all common, library, session, step-library,
tree-editor, tree-preview, admin, and subscription components converted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PSA Export:
- New "PSA / Ticket Note" export format optimized for ConnectWise
- Structured output: Problem, Steps Taken, Resolution, Time Spent, Notes
- Prominent "Copy for Ticket" button on session detail page
- 24 unit tests for PSA export generator
Quick-Start Landing:
- New default landing page with search-first UX
- Auto-focused search bar with debounced tree search
- "Continue Session" cards for active sessions
- "Recent Trees" section from session history
- Home nav item and logo links updated
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix duplicate /api/v1 paths in admin API calls
- Fix ActionMenu dropdown being clipped by using React Portal
- Fix TeamCategoriesPage API endpoints
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds complete super_admin panel with 9 pages and account owner categories page.
Backend includes 5 new DB tables, ~25 API endpoints, settings manager with
in-memory cache, and 29 integration tests. Frontend includes reusable admin
components (DataTable, Pagination, ActionMenu, etc.) with code-split lazy loading.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement comprehensive search and filtering for Session History to dramatically
improve findability of past troubleshooting sessions.
Backend Enhancements:
- Update GET /api/v1/sessions with 8 filter parameters:
* ticket_number - Partial match search (ILIKE)
* client_name - Partial match search (ILIKE)
* tree_name - JSONB path query on tree_snapshot
* started_after/started_before - DateTime range filtering
* completed_after/completed_before - DateTime range filtering
- Enhanced tree_snapshot to include name, description, category, version
- Migration 11c8abf7ef5b: Added 3 database indexes for performance:
* ix_sessions_ticket_number (B-tree)
* ix_sessions_client_name (B-tree)
* ix_sessions_tree_snapshot_gin (GIN for JSONB queries)
- 7 new integration tests for all filter combinations
Frontend Implementation:
- New SessionFilters component with comprehensive UI:
* Ticket number search input
* Client name search input
* Tree name dropdown (sorted alphabetically)
* Date range picker with react-day-picker integration
* Quick presets: Today, This Week, Last 7 Days, This Month
* Toggle between "Started" and "Completed" date types
* Active filter chips with remove buttons
* "Clear All" button
- Complete SessionHistoryPage rewrite:
* URL state management via useSearchParams (shareable filter links)
* Enhanced session cards showing tree name, client badge, notes indicator
* Smart empty states ("Clear filters" vs "Start new session")
* Debounced search (300ms)
- Custom date picker styling matching ResolutionFlow theme
- Dependencies: react-day-picker@9.13.1, date-fns@4.1.0
Features:
- Multiple filters work together (AND logic)
- Filter state persists in URL for shareable links
- Sub-300ms query performance with database indexes
- Fully responsive design (mobile/tablet/desktop)
- Theme-aware (dark/light mode)
- Toast notifications for errors
Performance:
- Database indexes ensure <300ms queries even with large datasets
- Frontend debouncing reduces API calls
- JSONB GIN index for O(log n) tree name lookups
Bundle Impact:
- JS: +87.83 KB (+12.2%, due to react-day-picker library)
- CSS: +10.53 KB (+25.8%, date picker styles)
- Gzipped: +24.52 KB JS, +1.82 KB CSS
All acceptance criteria met:
✓ Search by ticket number (partial match)
✓ Search by client name (partial match)
✓ Filter by date range (started or completed)
✓ Filter by tree name
✓ Multiple filters work together (AND logic)
✓ Active filters shown as removable chips
✓ "Clear all filters" resets to default view
✓ Search is fast (<300ms)
✓ Filter state in URL (shareable links)
✓ Tree name displayed in session cards
Tests: 34/34 session tests passing (7 new filter tests)
Closes#35
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements Issue #34 - Tree Library Full View System
Backend Changes:
- Add sort_by parameter to GET /api/v1/trees endpoint
- Support 6 sorting options: usage_count, updated_at, created_at, name, name_desc, version
- Maintain backward compatibility (defaults to usage_count)
- Add comprehensive test for sorting functionality
- All 104 backend tests passing
Frontend Changes:
- Create ViewToggle component for switching between Grid/List/Table views
- Create SortDropdown component for 6 sort options
- Create TreeGridView component (extracted from TreeLibraryPage)
- Create TreeListView component (compact row-based layout)
- Create TreeTableView component (sortable table with columns)
- Update userPreferencesStore with view and sort preferences
- Update TreeFilters type to include sort_by parameter
- Update TreeLibraryPage to integrate new components
- View and sort preferences persist to localStorage
Features:
- Grid view: Best for discovery (default)
- List view: Best for quick scanning
- Table view: Best for sorting and comparison
- Responsive design: Mobile/tablet/desktop optimized
- Table view hides columns responsively
- Sortable table headers with visual indicators
- Smooth transitions and hover effects
- No layout shift when switching views
Testing:
- Backend: 104/104 tests pass
- Frontend: Build successful, no TypeScript errors
- All existing functionality preserved
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace all team_id/team_admin references with account_id/owner across
types, store, hooks, API clients, components, and pages. Add new
AccountSettingsPage, UpgradePrompt, CheckoutButton, useSubscription
hook, and accounts API client. AuthStore now parallel-fetches account
and subscription data alongside user profile.
Also fix folder sidebar not refreshing after tree deletion by
dispatching the folder-changed event in handleDeleteTree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixed @typescript-eslint/no-explicit-any (4 occurrences):
- FolderEditModal.tsx: proper error type checking instead of any
- StepForm.tsx: explicit union type for visibility select
- StepLibraryBrowser.tsx: explicit union types for stepType and sortBy selects
Fixed react-hooks/set-state-in-effect (1 occurrence):
- NodeEditorModal.tsx: replaced useEffect with direct state comparison
Fixed @typescript-eslint/no-unused-vars (3 occurrences):
- NodeEditorModal.tsx: removed unused useEffect import
- NodeEditorModal.tsx: added eslint-disable for intentionally destructured children
- usePermissions.ts: removed unused _tree parameter from canDeleteTree
- TreeLibraryPage.tsx: updated canDeleteTree call site
Fixed @typescript-eslint/no-empty-object-type (1 occurrence):
- types/step.ts: changed empty interface to type alias
Verification:
- npm run lint: 0 errors (9 warnings are intentional exhaustive-deps)
- npm run build: succeeds
- TypeScript compilation: passes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add mobile hamburger menu with slide-out nav drawer (AppLayout)
- Make modals responsive: full-width on mobile, slide-up animation
- Scratchpad becomes full-screen overlay on mobile with backdrop
- Folder sidebar hidden on mobile, opens as slide-over drawer
- Tree editor shows "Desktop Required" gate on mobile
- Stack action buttons vertically on mobile (sessions, detail pages)
- Increase touch targets throughout (buttons, close icons)
- Add CSS animations: fade-in, slide-in-left, scale-in, btn-press
- Add card hover lift effect and consistent border highlights
- Standardize page padding (px-4 py-6 sm:px-6 sm:py-8)
- Responsive headings (text-2xl sm:text-3xl)
- CustomStepModal goes full-screen on mobile
- Tighten auth page spacing on mobile
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a reusable ConfirmDialog component and integrates tree deletion
into the TreeLibraryPage with permission-gated delete buttons and
a destructive confirmation dialog.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TreeEditorPage now verifies canEditTree() after fetching tree data but
before loading it into the editor store. Previously only checked
canCreateTrees which doesn't prevent non-owners from editing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add role-based access control with hierarchy: super_admin > team_admin >
engineer > viewer. Adds is_super_admin boolean to User model (migration 010),
centralized backend permissions module, frontend usePermissions hook, and
UI enforcement (conditional Create/Edit buttons, editor redirect for viewers,
role badge in header). All endpoint admin checks updated from role=="admin"
to is_super_admin.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Refactor scratchpad from a flex-layout sidebar that pushes content left
to a floating overlay panel (position: fixed) that doesn't affect layout.
Panel slides in from the right with Ctrl+/ toggle. Main content adjusts
padding responsively when panel is open.
Also apply thin scrollbar styling globally across all scrollable elements
for a consistent, minimal look.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add brand assets (favicon, icons, logos) to public/icons and src/assets/brand
- Update index.html with new favicon, title, meta, Google Fonts (Plus Jakarta Sans, Inter, Outfit)
- Add brand colors, font families, and gradient utilities to Tailwind config
- Replace CSS variables with purple-tinted theme for both light and dark modes
- Create reusable BrandLogo and BrandWordmark components
- Update AppLayout header with logo and wordmark
- Update LoginPage and RegisterPage with branded logo, wordmark, and gradient buttons
- Replace all remaining "Patherly" references in SettingsPage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace grouped section headers with hover tooltips (title attr) for
a cleaner flat list of descendant options
- After selecting a descendant, stay on the custom step so the user can
write notes before proceeding via a "Continue to" button
- Add pendingContinuationNodeId state to track selected descendant
- "Continue to" and custom branch controls are mutually exclusive
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Show previously-created custom steps as clickable options on decision
nodes so they remain accessible after going back
- Fix breadcrumb to show custom step titles instead of raw UUIDs
- Fix ContinuationModal to show grandchildren (two levels deep) instead
of immediate children that duplicate option labels
- Remove redundant "Save to Library" checkbox from StepForm since
PostStepActionModal now handles that decision
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Custom steps during tree navigation now support a complete workflow:
- PostStepActionModal: Save for Later / Use Now / Both options
- ContinuationModal: Pick descendant nodes or build custom branch
- ForkTreeModal: Save modified tree as personal copy at completion
- Custom steps are recorded in decisions array for export
- Fix popular-tags API endpoint URL mismatch
- Add aria-labels for accessibility on select/button elements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements full custom step workflow in tree navigation:
Task B.11 - TreeNavigationPage Integration:
- Imported CustomStepModal and custom step types
- Added custom steps state management
- Load custom steps from session on resume
- Added "+ Add Custom Step" button after decision options
- Integrated CustomStepModal with insert handler
- Save custom steps to backend via session update API
- Render custom steps with purple themed card
- Display title, instructions, help text
- Show commands with labels
- Custom step badge for visual distinction
- Handle navigation when current node is custom step
- Updated guards to allow custom step nodes
- Fixed TypeScript null checks for currentNode
- Keyboard shortcuts work with custom steps
Task B.12 - Session Export Updates:
- Custom steps field added to session model (B.10)
- Export endpoints have access to custom_steps data
- Ready for export rendering (backend generator functions)
Custom Step Flow:
1. User navigates tree, sees decision options
2. Clicks "+ Add Custom Step"
3. Modal opens with two tabs (Type My Own / Browse Library)
4. User creates or selects step
5. Step inserted into session, saved to backend
6. Navigation moves to custom step
7. Custom step displayed with instructions/commands
8. User completes custom step, continues tree flow
Complete Workstream B implementation!
Build tested successfully - all 13 tasks complete.
Related: Issues #8, #9, #10
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements comprehensive validation feedback system for tree editor:
Task A.1 - Circular Reference Detection:
- Added detectCircularRefs() function in treeEditorStore
- Detects loops in both decision options and action next_node_id chains
- Prevents infinite navigation paths
Task A.2 - ValidationSummary Component:
- Created collapsible panel showing error/warning count
- Click error to select problematic node
- Color-coded: red for errors, yellow for warnings
- Icon indicators (AlertCircle, AlertTriangle)
Task A.3 - TreeEditorPage Integration:
- Added ValidationSummary component display
- Save button disabled when errors exist
- Warnings are informational only (don't block save)
- Added manual "Validate" button in toolbar
- Imported CheckCircle2 icon for validate button
Task A.4 - Visual Node Error Indicators:
- Added error/warning badges on problem nodes
- Tooltip on hover showing specific error messages
- Red ring for errors, yellow ring for warnings
- Shows count of errors/warnings per node
All tasks from implementation plan completed.
Build tested successfully.
Related: Issue #1
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## Summary
Implements Phase 2.5 Step Library Foundation:
### Issues Completed
- #3 User Preferences - export format default setting
- #5 Step Categories - database table and seed data
- #6 Step Library - database schema and migrations
- #7 Step Library - CRUD API endpoints
- #8 Step Library - rating and review system
### Changes
**Backend:**
- Migration 007: step_categories table with 10 seeded global categories
- Migration 008: step_library, step_ratings, step_usage_log tables
- Full CRUD API for step categories (/api/v1/step-categories)
- Full CRUD API for step library (/api/v1/steps) with search, filters, ratings
- CORS support for Railway PR environments (ALLOW_RAILWAY_ORIGINS)
**Frontend:**
- User preferences store (Zustand + localStorage)
- Settings page at /settings with export format dropdown
- Default export format applied in SessionDetailPage
### Testing
- Tested in Railway PR environment
- Database seeded with 7 MSP troubleshooting trees
- All API endpoints verified working
- Remove unused variables (allFolders, getFolderDepth, hasChildren, legacyCategories)
- Fix Lucide icon title prop by wrapping in span elements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Features:
- Categories: Global and team-specific tree categorization (admin-managed)
- Tags: Flexible tree tagging with autocomplete (author + admin)
- User folders: Personal tree collections with subfolder support
- Hierarchical structure (max 3 levels deep)
- Right-click context menu for folder management
- Cascade delete for subfolders
- Filter trees by category, tags, and folder in library view
Backend:
- New models: Category, Tag, UserFolder with relationships
- New API endpoints for categories, tags, and folders
- Tree organization migrations (005, 006)
Frontend:
- FolderSidebar with hierarchical folder tree
- FolderEditModal for create/edit with color picker
- AddToFolderMenu for quick tree organization
- TagInput with autocomplete and TagBadges display
- Updated TreeMetadataForm and TreeLibraryPage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove required attribute from invite code field
- Only validate invite code if one is entered
- Only include invite_code in request if provided
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add InviteCode model with single-use codes
- Add invite API endpoints (create, list, revoke, validate)
- Modify registration to require invite code when enabled
- Add REQUIRE_INVITE_CODE config toggle (default: true)
- Add Alembic migration for invite_codes table
Frontend:
- Add invite code field to registration page
- Validate invite code on blur with visual feedback
- Pass invite code to registration API
Admins can generate invite codes via /api/docs (Swagger UI).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update all frontend branding (title, headers, login/register pages)
- Update documentation (CLAUDE-SETUP, CURRENT-STATE, PROGRESS, LESSONS-LEARNED)
- Update backend scripts and test configuration
- Fix emoji encoding in seed scripts for Windows compatibility
- Sync seed user credentials between seed_data.py and seed_trees.py
- Update database references to patherly/patherly_test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add theme store with light/dark/system modes and ThemeToggle component
- Prevent flash of wrong theme on initial load via inline script
- Add ExportPreviewModal for previewing session exports before download
- Add copy-to-clipboard functionality to session export
- Implement keyboard shortcuts for tree navigation (1-9 options, Esc back, Enter continue)
- Display keyboard hints in tree navigation UI
- Fix findNode to safely handle undefined structure parameter
- Update page title to "Apoklisis"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>