Commit Graph

60 Commits

Author SHA1 Message Date
Michael Chihlas
58a55f4d88 feat: remove workspace system, add pinned flows and label renames
Replace workspace system with pinned flows API (pin/unpin/list/reorder).
Rename user-facing labels: Tree→Flow, Procedure→Project. Add sidebar
nav sub-items for flow type filtering. Remove 11 workspace files,
add migrations 037-038, clean all workspace references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 12:06:10 -05:00
Michael Chihlas
d6f4286570 feat: add workspace system and sidebar layout (UI design system Phase A+B)
Backend: Workspace model, migration (036), schemas, CRUD API endpoints.
Adds workspace_id to trees and categories, seeds 4 default workspaces
per account, auto-assigns existing trees by tree_type.

Frontend: Complete AppLayout rewrite from top-nav to CSS Grid shell
with persistent sidebar + topbar. New components: WorkspaceSwitcher,
NavItem, CategoryList, TagCloud, TopBar, Sidebar. Dashboard components:
QuickStats, FiltersBar, SectionGroup, TreeListItem, SessionsPanel.
WorkspaceStore with localStorage persistence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 01:16:33 -05:00
chihlasm
57f429f33b feat: session sharing frontend (#76)
* feat: add session sharing types, API client, and utilities

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add SessionTimeline and ActionMenu reusable components

SessionTimeline extracts timeline/checklist rendering from SessionDetailPage
into a reusable component for both authenticated and public session views.
ActionMenu provides a dropdown action menu with keyboard/click-outside dismiss.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add ShareSessionModal and integrate into SessionDetailPage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add Share Progress popover to TreeNavigationPage

Replace the single "Copy for Ticket" button with a "Share Progress"
popover that offers three actions: Copy Progress Summary (existing PSA
export flow), Copy Share Link (auto-creates account-only share if
needed), and Manage Share Links (opens ShareSessionModal).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add public SharedSessionPage with tree preview

Add the public-facing shared session page at /share/:shareToken that
renders shared sessions without authentication. Includes error handling
for 401 (redirect to login), 403 (access denied), 404 (not found),
and 410 (expired). The page features a minimal header, session metadata,
SessionTimeline component, and a new SharedSessionTreePreview component
that renders the decision tree structure with the path taken highlighted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add My Shares management page with nav link

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address code review issues in session sharing

- Add useCallback for loadShares in ShareSessionModal (React hook deps)
- Use TreeStructure type instead of Record<string, unknown> for type safety
- Fix login redirect format to match LoginPage's expected state shape

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add focused tests for session sharing utilities and API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve tree_structure type compatibility for shared session views

- Use TreeStructure & Record<string, unknown> intersection for JSONB flexibility
- Add explicit cast in SharedSessionTreePreview for recursive node rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add session sharing learnings to CLAUDE.md

Add gotchas #12 (TreeStructure vs Tree types) and #13 (login redirect
state format), note about npm run build strictness, and public route
pattern to Common Tasks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: procedural editor UX improvements

Add URL intake field type, fix variable name editing collapsing fields
(index-based keys/updates), auto-generate variable names by field type,
add section header as first-class step type, and simplify step editor
with "More Options" collapsible for advanced fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: allow section_header step type in validation, improve tag input

- Add 'section_header' to VALID_STEP_TYPES in backend validation so
  procedural flows with section headers can be published
- Replace procedural editor's inline tag input with TagInput component
  (supports autocomplete, Tab, comma, semicolon, and paste splitting)
- Add semicolon delimiter support to TagInput component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add type-aware routing for procedural flows

Centralizes tree navigation routing via getTreeNavigatePath helper.
Fixes all pages to route procedural sessions to /flows/:id/navigate
instead of /trees/:id/navigate. Adds safety redirect in troubleshooting
navigator and resume support in procedural navigator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove unused index prop from IntakeFieldEditor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:08:17 -05:00
chihlasm
350c977eda feat: add procedural flows with intake forms, navigation, and seed templates
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>
2026-02-14 04:13:52 -05:00
chihlasm
303570ca2c feat: add sensitive data redaction to export (Phase C)
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>
2026-02-14 00:11:20 -05:00
Michael Chihlas
0a67a846de feat: add summary block generation to all 4 export generators
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:57:55 -05:00
Michael Chihlas
c8f9cc1c4b feat: add format-aware command output truncation for standard detail level
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:56:16 -05:00
Michael Chihlas
28c969f06e feat: add [CUSTOM] markers to custom steps in all 4 export generators
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:54:45 -05:00
Michael Chihlas
ea0f79fac0 feat: add include_summary and detail_level to SessionExport schema
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 12:53:19 -05:00
Michael Chihlas
f8a14d8b4c fix: skip RESOLUTION section in PSA export for incomplete sessions
Mid-session "Copy for Ticket" no longer shows a misleading Resolution
section that echoed the last step's answer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 10:50:55 -05:00
Michael Chihlas
8797ae0261 feat: add step cutoff and mid-session export support
- max_step_index slices decisions in all 4 export formats
- Only set exported=True when session is completed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:58:03 -05:00
Michael Chihlas
69c95065b6 feat: add Resolution and Next Steps sections to all export formats
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:54:50 -05:00
Michael Chihlas
ae701ef066 feat: save next_steps on session completion and update
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:42:19 -05:00
Michael Chihlas
ec5c91c8e4 feat: add next_steps column and update session schemas
- Add next_steps TEXT column to sessions table via migration 034
- Add include_outcome_notes, include_next_steps, max_step_index to SessionExport
- Add next_steps to SessionUpdate, SessionResponse, SessionComplete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 08:32:20 -05:00
chihlasm
ad59446332 feat: user management — admin create, password reset, archive/delete, quick invite
Phase 1: must_change_password enforcement + change password endpoint/page
Phase 2: Admin user creation (M365-style) with temp password
Phase 3: Password reset (self-service forgot + admin-triggered)
Phase 4: User archive (soft delete) + hard delete with precheck
Phase 5: Quick invite from admin Users page

Also fixes:
- Auto-create subscription for accounts missing one
- Hard delete precheck ignores sole-member personal accounts
- Seed script patches tree nodes for validation compliance

Migrations: 031 (must_change_password), 032 (password_reset_tokens), 033 (user soft delete)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:42:51 -05:00
chihlasm
577a2fbf2a feat: add command output capture to troubleshooting sessions (#57)
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>
2026-02-12 00:57:33 -05:00
chihlasm
3c47292eaf feat: add resend capability for platform and account invite codes
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>
2026-02-11 23:45:23 -05:00
Michael Chihlas
50cb0fc7f0 feat: admin invite codes with plan assignment + user detail page
- 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>
2026-02-11 21:42:58 -05:00
Michael Chihlas
ca4ce7cad6 Implement session outcomes, step timing, and live timer fixes 2026-02-11 17:52:12 -05:00
chihlasm
eac6e184ec feat: add dual-mode tree editor with Code Mode, variables, and markdown sync
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>
2026-02-10 09:45:26 -05:00
chihlasm
4f8b7dd7ca feat: add PSA ticket export format and Quick-Start landing page
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>
2026-02-08 19:36:51 -05:00
chihlasm
b97596d286 refactor: tech debt reduction - extract hooks, deduplicate helpers, update deps, add CI
- Extract useCustomStepFlow hook from TreeNavigationPage (1040 → 759 lines)
- Create core/filters.py with shared tree/step visibility filters
- Create services/export_service.py from session export logic
- Add GitHub Actions CI/CD pipeline (pytest + lint + build)
- Add GIN index migration for full-text search on trees
- Update FastAPI 0.128.5, Pydantic 2.12.5, SQLAlchemy 2.0.46, +5 more
- Fix regex → pattern deprecation in Query() params

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 08:14:22 -05:00
Michael Chihlas
b570f8415f feat: implement full admin panel with dashboard, user management, and platform settings
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>
2026-02-08 06:05:59 -05:00
Michael Chihlas
c7b2c59ef6 feat: implement tree sharing, draft trees, and session-to-tree conversion (Issues #16, #25, #17)
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>
2026-02-07 23:06:13 -05:00
Michael Chihlas
9f92547309 feat: implement session history search and filtering (Issue #35)
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>
2026-02-07 21:17:25 -05:00
Michael Chihlas
89e09edc64 feat: add tree library view system with grid/list/table modes and sorting
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>
2026-02-07 20:36:20 -05:00
Michael Chihlas
ffb14cd014 feat: add tree forking, custom step tracking, and session sharing
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>
2026-02-07 19:10:47 -05:00
chihlasm
974e86a502 fix: resolve circular FK between users and accounts on registration
Account.owner_id and User.account_id are both NOT NULL, creating a
circular dependency that prevents inserting either row first. Fix by:
1. Making owner_id nullable (set immediately after user creation)
2. Creating Account before User, then setting owner_id after flush
3. Removing NOT NULL enforcement on owner_id in migration 020

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 02:55:53 -05:00
chihlasm
e0089a9c5a feat: update all endpoints and schemas for account-based model
Replace team_id with account_id across all API endpoints (trees,
categories, tags, steps, step_categories, admin, auth). Add new
accounts and webhooks endpoints. Registration now atomically creates
Account + Subscription, with account_invite_code bypassing the
platform invite gate.

Schemas updated for account_id/account_role. 82 tests passing
including 18 new tests for accounts, subscriptions, and permissions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 02:39:01 -05:00
chihlasm
4ccb93ee31 feat: add account-based subscription model with migrations
Transition from team-based to account-based multi-tenancy (Free/Pro/Team).
Migrations 016-020 create accounts, subscriptions, plan_limits, and
account_invites tables, then migrate existing users and content FKs.

New models: Account, Subscription, PlanLimits, AccountInvite.
Updated models add account_id alongside existing team_id (coexistence
for safe two-PR deployment). Permissions and deps refactored for
account_role instead of is_team_admin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 02:38:47 -05:00
chihlasm
1e57aa8323 fix: escape SQL wildcards in tag search autocomplete
The % and _ characters in user search input are now escaped before
the LIKE query, preventing unintended wildcard matching in tag search.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:26:35 -05:00
chihlasm
94ec19cf07 fix: only register debug endpoint when DEBUG=True
The /debug/cors endpoint is now conditionally registered, preventing
information leakage about CORS configuration in production.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:24:02 -05:00
chihlasm
5ae22e041f fix: clean up folder and tag assignments on tree soft delete
When a tree is soft-deleted, folder assignments and tag assignments are
now removed from junction tables. Tag usage counts are decremented with
a floor of zero to prevent negative counts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:23:24 -05:00
chihlasm
02e00963e1 feat: add password complexity validation
Passwords must now contain at least one uppercase letter, one lowercase
letter, and one digit (in addition to the existing 10-char minimum).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 00:20:21 -05:00
chihlasm
33368688b2 feat: upgrade tree deletion to soft delete with deleted_at timestamp
Adds deleted_at and deleted_by columns to trees table for proper soft
delete tracking. Supports future 30-day restore window functionality.
The delete endpoint now sets both is_active=False (backward compat) and
deleted_at/deleted_by. Migration backfills existing is_active=False rows.

Fixed ambiguous FK relationship between User/Tree models by adding
explicit foreign_keys to both sides of the author relationship.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 23:33:05 -05:00
chihlasm
3a5ac0f201 feat: add audit log table and integration with admin/tree endpoints
Creates AuditLog model with JSONB details column for tracking admin
actions. Integrates log_audit() helper into admin endpoints (role
change, team admin toggle, deactivate, activate) and tree delete.
IP address column reserved for future Railway proxy header support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 23:28:41 -05:00
chihlasm
02d06acfb8 feat: add super admin bypass in tree list filter
Super admins now see all trees regardless of ownership, team, or
public/default status. Previously the build_tree_access_filter function
had no super_admin check, so admins could only see their own trees plus
public/default/team trees.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 23:25:56 -05:00
chihlasm
71ba0b95a5 fix: high-severity security hardening (Phase B permissions audit)
Phase B addresses 7 high-severity gaps from the permissions audit:

- B1: Enforce tree access check on session start via can_access_tree
- B2: Replace all inline permission helpers with centralized permissions.py
- B3: Fix require_engineer_or_admin to check is_team_admin before role
- B4: Add is_active field on User with enforcement in get_current_active_user
- B5: Add admin user management endpoints (list, get, role, team-admin, deactivate, activate)
- B6: Add rate limiting on auth/invite endpoints via slowapi (disabled in DEBUG)
- B7: Implement refresh token rotation with JTI-based revocation and meaningful logout

Also reduces access token TTL from 15 to 5 minutes and updates CLAUDE.md
with SaaS/MSP context for future planning sessions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 22:44:05 -05:00
chihlasm
3e0fb92012 fix: critical security hardening (Phase A permissions audit)
- Remove role field from UserCreate schema, hardcode 'engineer' at registration
- Escape all user content in HTML export with html.escape() (XSS fix)
- Add field_validator to reject default SECRET_KEY when DEBUG=False
- Add CHECK constraint on users.role ('engineer'|'viewer') + migration 011
- Fix test_admin fixture to properly grant is_super_admin via ORM
- Fix circular FK (users↔invite_codes) in test DB setup with DROP SCHEMA CASCADE
- Add 5 new security tests (role validation + XSS prevention)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 22:04:37 -05:00
chihlasm
34daa26a67 feat: implement RBAC permissions system
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>
2026-02-05 02:42:44 -05:00
Michael Chihlas
6b8b29571e fix: token refresh and seed tree visibility
Fix broken JWT token refresh that caused "Failed to load trees" after
idle timeout. The refresh endpoint expected token as query param but
frontend sent it as Authorization header. Added proper dependency
(get_refresh_token_payload) and refresh queue to handle concurrent 401s.

Also fix seed trees not being visible to non-admin users by updating
the seed script to set is_public/is_default on existing trees.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:41:37 -05:00
Michael Chihlas
7824cddd71 feat: include scratchpad in session export (markdown, text, HTML)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 02:49:11 -05:00
Michael Chihlas
6da2044b20 feat: add PATCH endpoint for session scratchpad
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 02:48:10 -05:00
Michael Chihlas
7d0000827b feat: add scratchpad field to session model and schemas
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 02:47:22 -05:00
Michael Chihlas
83df48291a feat: Complete backend and docs rebrand from Patherly to ResolutionFlow
Update APP_NAME, OpenAPI metadata, log messages, root endpoint response,
model docstrings, seed script comments, README heading, and CLAUDE.md
branding references. Frontend rebrand was completed in PR #26; this
covers everything else.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 00:41:22 -05:00
Michael Chihlas
009c60fbc3 feat: Add custom step creation and backend support (Phase 3A: B.8-B.10, B.13)
Implements custom step creation forms and backend persistence:

Task B.8 - StepForm Component:
- Comprehensive form for creating custom steps
- Step type selection (decision/action/solution) with descriptions
- Required fields: title, instructions (markdown supported)
- Optional fields: help text, commands (dynamic array), category, tags
- Visibility control (private/team/public)
- Save to library checkbox
- Full validation with error display
- Dynamic command management (add/remove, label + command)
- Tag input with Enter key support

Task B.9 - CustomStepModal:
- Tabbed modal interface
- Tab 1: "Type My Own" - embeds StepForm
- Tab 2: "Browse Library" - embeds StepLibraryBrowser
- Handles both saved steps (API) and drafts (no save)
- Loading states during step creation
- Error handling with user feedback
- Returns Step or CustomStepDraft to parent

Task B.10 - Backend Custom Steps Support:
- Database migration: add custom_steps JSONB column to sessions
- Updated Session model with custom_steps field
- Updated SessionResponse schema with custom_steps
- Updated SessionUpdate schema to accept custom_steps
- Migration ready to run: 4cdb5cba1aff

Task B.13 - Session Types Updates:
- Added CustomStep and CustomStepDraft interfaces
- Updated Session interface with custom_steps field
- Updated SessionUpdate interface
- Exported step types from types/index.ts
- Full TypeScript support for custom step integration

Remaining tasks: B.11 (TreeNavigationPage integration), B.12 (Export)
Build tested successfully.

Related: Issues #8, #9, #10

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 19:15:36 -05:00
Michael Chihlas
d1201cc584 Fix CORS to include allowed_origins when using Railway regex
The CORS middleware was only using the regex pattern for *.up.railway.app
when ALLOW_RAILWAY_ORIGINS was enabled, ignoring the explicit allowed_origins
list that includes custom domains like app.patherly.com.

Now includes both allow_origins and allow_origin_regex so custom domains
work alongside Railway PR environments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 10:31:59 -05:00
chihlasm
7803dc4522 Add step library foundation and user preferences (#24)
## 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
2026-02-03 02:07:46 -05:00
chihlasm
fafdaa50a5 Add tree organization system with categories, tags, and folders
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>
2026-02-02 01:31:13 -05:00
Michael Chihlas
2d99c52025 Add public/private visibility for trees
- Add is_public field to Tree model (private by default)
- Update access control: users see default trees, public trees, or their own
- Update all tree endpoints (list, search, get, categories) with new visibility logic
- Default/system trees are automatically marked as public
- Add migration 004 to add is_public column and update existing defaults
- Fix pydantic settings to ignore extra env vars (DATABASE_URL_SYNC)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:53:19 -05:00