- 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>
Add monaco-editor to frontend deps, gitignore temp files (test_results.txt,
stats.html, .agents/), and add VS Code workspace config.
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>
Move completed design/implementation docs from docs/plans/ to docs/archive/
to keep the plans folder focused on active and future work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
react-refresh/only-export-components disallows mixing component and
non-component exports. Moved the editor ref to monacoEditorRef.ts.
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>
Remove outdated purple gradient/theme toggle references, add monochrome
design system patterns and component guidelines for future sessions.
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>
Enable moving nodes between different parents in the tree editor.
Drop targets show blue indicator for valid drops and red pulsing
glow for invalid drops (e.g., dropping onto solution nodes or
onto descendants of the dragged node).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Grip-only drag initiation (prevents conflict with click-to-select)
- onDragEnd on each draggable item (clears ghost state after failed drops)
- Trailing drop zone after last child (enables drop-to-last-position)
- Suppress cross-parent drag indicators (no misleading visual feedback)
- onDragLeave handler to clear drop indicators when cursor exits
- Source parent tracking threaded through component tree
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>
Add Vitest + testing-library/react + jsdom for frontend testing.
Tests cover: cn() utility (6), usePermissions hook (27), useTreeValidation
hook (22), and userPreferencesStore (6). CI updated to run frontend tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the 31 migration files, naming conventions, revision chain,
circular FK workaround, NULL casting gotcha, and migration history table.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update python-jose from 3.3.0 to 3.5.0 to fix:
- CVE-2024-33663: Algorithm confusion with ECDSA keys (High)
- CVE-2024-33664: JWT bomb DoS via high compression ratio (High)
Remaining accepted risk: ecdsa CVE-2024-23342 (Minerva timing attack)
- No fix available (maintainer considers side-channel attacks out of scope)
- Non-exploitable in this app: JWTs use HMAC (HS256), not ECDSA signing
All 189 tests pass. npm audit: 0 vulnerabilities.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add missing `solution` field to solution-type nodes in test tree structures
(required by `can_publish_tree` validation for published trees)
- Fix `AsyncClient(app=...)` → `ASGITransport(app=...)` in test_save_session_as_tree
(httpx deprecated the `app` parameter in favor of transport)
- All 189 tests now pass (was 84 passed, 1 failed)
Files fixed: conftest.py, test_permissions_account.py, test_subscription_limits.py,
test_trees.py, test_save_session_as_tree.py
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>
Backend features:
- Tree sharing via secure tokens with expiration (Issue #16)
- Draft tree status with conditional validation (Issue #25)
- Save session as custom tree with fork tracking (Issue #17)
- Tree validation system for publish requirements
- Session-to-tree conversion preserving custom steps
Database migrations:
- 024: Tree sharing (tree_shares table, visibility field)
- 025: Tree status field (draft/published)
- 25b: Merge migration for indexes
New endpoints:
- POST /api/v1/trees/{id}/share - Generate share token
- GET /api/v1/shared/{token} - Public tree access
- POST /api/v1/trees/{id}/can-publish - Validate tree
- POST /api/v1/sessions/{id}/save-as-tree - Convert session
Test coverage:
- 20 tests for draft trees functionality
- 14 tests for session-to-tree conversion
- 15 tests for tree sharing
Co-Authored-By: Claude Sonnet 4.5 <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>
Implement three foundational schema features from the design doc:
- Tree forking with lineage tracking (migration 022): parent_tree_id,
root_tree_id, fork_depth columns with self-referential FKs and
composite analytics index
- Custom step enhancement: CustomStepSchema with source tracking
(ad-hoc, step-library, forked-tree) for backward-compatible JSONB
- Session sharing (migration 023): session_shares and session_share_views
tables with account-scoped visibility, cryptographic tokens, view
tracking, and allow_public_shares account policy
Includes 21 new integration tests (9 forking, 12 sharing), SaaS
consultant-recommended denormalizations, rate limiting on public share
access, and test fixture fix for invite code requirement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comprehensive schema design for three critical foundational features:
1. Tree Forking Model (Issue #11)
- Add parent_tree_id, fork_reason, parent_updated_at to trees
- Self-referential relationship with orphaning on parent delete
- Update detection mechanism for "parent tree updated" notifications
2. Session Custom Steps Enhancement (Issues #4-#7 partial)
- Backward-compatible JSONB enhancement (no migration)
- Track step source (ad-hoc, library, forked-tree)
- Link to StepLibrary for usage analytics
- Support "save session as tree" reconstruction
3. Session Share Tokens (Issue #15)
- New session_shares table with token-based access
- New session_share_views table for detailed analytics
- Account-level policy: allow_public_shares
- Public vs account-only visibility with permission checks
All schema changes designed for backward compatibility and minimal
migration complexity. Establishes durable domain model that future
features depend on.
Migration plan: 022 (tree forking), 023 (session sharing)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>