Commit Graph

33 Commits

Author SHA1 Message Date
chihlasm
9462d8b15a feat: procedural editor redesign with collapsible sections and DnD (#84)
* docs: add procedural/maintenance editor redesign design

Collapsible sections, fixed-height layout, drag-to-reorder steps,
maintenance schedule section, and step list UX improvements.

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

* docs: add procedural editor redesign implementation plan

7 tasks across 7 phases: collapsible sections, fixed-height layout,
step list improvements, drag-to-reorder, maintenance schedule section.

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

* feat: restructure procedural editor with collapsible sections and fixed-height layout

Convert scrolling document layout to fixed-height editor with accordion-mode
collapsible sections for Details and Intake Form. Step list now gets all
remaining height with independent scrolling. Add CollapsibleEditorSection
component with ARIA attributes (aria-expanded, aria-controls).

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

* feat: add step count with time estimate header and auto-scroll to new steps

Remove outer card wrapper from StepList (now rendered in scrolling container).
Header shows total estimated minutes when steps have time estimates. Auto-scrolls
to newly added steps using ref + scrollIntoView.

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

* feat: add drag-to-reorder steps with @dnd-kit

Wrap step list in DndContext + SortableContext. Each step/section header
gets a SortableStepWrapper with useSortable. Drag handles have accessible
labels and keyboard support. procedure_end stays non-draggable and always
last. Expanded steps are disabled for dragging. Array-index reorder only.

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

* feat: add MaintenanceScheduleSection with schedule builder and summary

Schedule draft state is local UI only (not in store). Hydrates form from
existing schedule on load. Includes getScheduleSummary helper for collapsed
section display. Two-stage save: tree first, schedule second. Schedule
failure shows actionable error without rolling back tree save.

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

* feat: wire maintenance schedule section into procedural editor

Add collapsible Schedule section for maintenance flows with accordion
integration. Schedule summary shows frequency, time, and target count
when collapsed. New maintenance flows default to schedule section expanded.
Two-stage save preserved: tree saved first, schedule managed independently.

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

* fix: resolve lint issues in maintenance schedule and editor page

Move getScheduleSummary to scheduleUtils.ts to satisfy react-refresh
only-export-components rule. Add onScheduleLoaded to useEffect deps.

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

* docs: add design and implementation revision documents

Revision docs correct original plans: schedule persistence via API
endpoints (not tree_structure), array-index reorder (no display_order),
store minimum-one-step invariant, accordion mode, ARIA requirements,
and two-stage save orchestration with failure handling.

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

* feat: auto-seed PR environments with SEED_ON_DEPLOY flag

Release command now runs migrations + seeds test users when
SEED_ON_DEPLOY=true. Tree seeding runs as a background task
on startup via HTTP API. Everything is idempotent and non-fatal.

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

* fix: add httpx to requirements for PR environment seeding

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

* feat: seed all flow types (v2, procedural, maintenance) on deploy

Runs seed_trees, seed_trees_v2, seed_procedural_flows, and
seed_maintenance_flows sequentially as background tasks when
SEED_ON_DEPLOY=true. Each script failure is non-fatal.

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

* chore: trigger redeploy for full seed

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 08:39:25 -05:00
chihlasm
1e7eeb8daa feat: add feedback notification and confirmation emails to EmailService
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:41:30 -05:00
chihlasm
dc93e96a20 feat: add FEEDBACK_EMAIL config setting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 17:39:52 -05:00
chihlasm
94de29b5f2 feat: canvas UX fixes — scroll, fullscreen, InfoTip tooltips, answer stub system (#80)
* feat: Add TreeCanvasNode inline editor card component

Replaces modal-based node editing with inline expand/collapse cards.
Each card shows node type, title, and options in compact mode, then
renders the full edit form inline on expand — no modal required.

Local draft state with save/cancel prevents premature store writes.

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

* feat: Add TreeCanvas layout with visual branching and orchestration

Replaces NodeList + TreePreviewPanel with a single full-width canvas.
Decision nodes branch horizontally; action/solution nodes flow vertically.
Inline type picker adds nodes without modal interruption. Handles pending
link resolution, inbound reference cleanup on delete, and selection sync.

CSS dot-grid background + connector lines for structure clarity.

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

* refactor: Update forms for inline safety, add MetadataSidePanel, update layout

- NodeFormDecision: option reorder via onUpdate (no premature store writes)
- NodePicker: add allowCreate prop (default true) to hide Create New options
  during inline canvas editing, preventing side-effect node creation
- MetadataSidePanel: 320px right slide-in overlay wrapping TreeMetadataForm,
  closes on backdrop click, close button, and Escape key
- TreeEditorLayout: Flow mode now renders full-width TreeCanvas + MetadataSidePanel
  overlay; Code mode unchanged (Monaco + preview split)

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

* feat: Wire toolbar metadata toggle and integrate canvas layout

- Add isMetadataOpen state in TreeEditorPage
- Add Metadata toolbar button (visible in Flow mode only)
- Auto-close metadata panel when switching to Code mode
- Pass isMetadataOpen/onCloseMetadata props through TreeEditorLayout
- Update Flow mode toggle tooltip to reflect new canvas editing

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

* docs: add canvas UX fixes design doc (scroll, tooltips, answer stubs)

Captures approved design for three post-implementation UX improvements
to the tree canvas editor: card scroll fix, info tooltip replacement for
hint text, and the new 'answer' node type for sketching decision branches
before assigning types.

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

* docs: add implementation plan for canvas UX fixes

12-task plan covering scroll fix, info tooltips, and answer stub
node type. Each task has exact file paths, code, and build
verification steps.

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

* fix: make canvas card expanded area scrollable with sticky header

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

* feat: add fullscreen toggle to Modal, enable in NodeEditorModal

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

* feat: add reusable InfoTip component for field-level help

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

* fix: replace hint paragraphs with InfoTip tooltips in NodeFormDecision

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

* fix: replace hint paragraphs with InfoTip tooltips in NodeFormAction

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

* fix: replace hint paragraphs with InfoTip tooltips in NodeFormResolution

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

* feat: add 'answer' to NodeType union for branch placeholder stubs

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

* feat: add AnswerStubCard component for unresolved branch placeholders

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

* fix: guard NODE_TYPE_CONFIG lookup against 'answer' type

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

* feat: redesign NodeFormDecision to label-only options, remove NodePicker

Users now type answer labels only. Stub nodes are created automatically
by TreeCanvas when the decision node is saved.

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

* feat: auto-create answer stubs on decision save, render AnswerStubCard

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

* fix: add answer type to all Record<NodeType> icon and color maps

Fixes NodeList, ContinuationModal, NodePicker, and TreePreviewNode.

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

* feat: allow 'answer' type in tree drafts, block on publish

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

* feat: block publish if unresolved answer stub nodes exist

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

* feat: serialize 'answer' stub nodes in markdown output

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

* fix: add defensive guard for answer nodes in session navigation

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

* feat: add delete button with confirmation to AnswerStubCard

Adds an inline delete flow to answer stub placeholder cards:
- Trash icon button (top-right, subtle) visible in idle state
- Click reveals "Delete this stub?" confirmation with Delete/Cancel
- Confirmed delete calls onDelete(nodeId) wired to handleDelete in TreeCanvas

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

* fix: prevent category Cancel overflow and add Tab/Enter to create options

- TreeMetadataForm: add min-w-0 + shrink-0 to keep Cancel button in-panel
- NodeFormDecision: Tab or Enter on the last non-empty option input adds a
  new option and auto-focuses it; empty last input lets Tab pass through normally

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

* fix: re-sync draft from store when canvas card is opened

When a decision node is saved with new options, stub next_node_id values
are written back to the store. But the local draft was initialized once at
mount and never refreshed, so reopening the card gave a stale draft with
empty next_node_ids — causing duplicate stubs on every subsequent save.

Fix: reset draft from the live node whenever isExpanded transitions to true.

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

* fix+feat: blank options, stub card dismiss, collapsible subtrees

- TreeCanvas: strip blank-label options on save so they don't generate
  stubs; also filter them from the unlinked-option add-button list
- AnswerStubCard: collapse type-picker when clicking outside the card
- TreeCanvasNode: add subtree collapse toggle button (ChevronsDownUp icon)
  visible in compact mode when the node has children
- TreeCanvas: track collapsedNodeIds; hide subtree behind a clickable
  "N nodes hidden" pill when collapsed

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

* fix: stop connector fork line from overlapping child cards

Replace the two-element approach (separate fork line + child lanes div with
mismatched maxWidth values) with a single relative-positioned container.
The fork line is absolutely positioned and its left/right are calculated from
the number of children so it spans exactly from the center of the first lane
to the center of the last lane.

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

* feat: replace Show Drafts checkbox with Drafts tab in Flow Library

- Remove the out-of-place checkbox; add 'Drafts' as a tab alongside
  All | Troubleshooting | Projects | Maintenance
- Drafts tab sets showDrafts=true + typeFilter='all' so the API filter
  still works correctly via include_drafts
- Move SortDropdown to the right side next to ViewToggle, so both
  secondary controls are grouped together

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 12:52:08 -05:00
chihlasm
db715929e7 fix: stabilize maintenance flow run/resume and procedural scrolling 2026-02-17 20:12:07 -05:00
chihlasm
6240d68d09 fix: apply code review security and robustness fixes
- Add require_engineer_or_admin to POST/PUT/DELETE in target_lists.py (blocks viewers from write ops)
- Add require_engineer_or_admin to POST/PATCH in maintenance_schedules.py (blocks viewers from write ops)
- Add team ownership guard in batch_launch_sessions after active/published checks (Fix 2)
- Wrap scheduler.remove_job in try/except for SchedulerNotRunningError and JobLookupError (Fix 3)
- Recompute next_run_at when is_active flips to True, capturing was_active before update (Fix 4)
- Add optional batch_id and target_label fields to Session type; remove unsafe cast in MaintenanceFlowDetailPage.tsx (Fix 5)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 16:15:19 -05:00
chihlasm
5abff028bc feat: APScheduler integration for maintenance flow auto-session creation
- Add backend/app/core/scheduler.py with AsyncIOScheduler, CronTrigger-based
  job registration, and _fire_maintenance_schedule to create batch sessions
- Wire scheduler.start()/load_all_schedules()/shutdown() into main.py lifespan
- Call register_schedule() in create_schedule endpoint after commit
- Call register_schedule()/unregister_schedule() in update_schedule based on is_active
- Add TreeShare to models/__init__.py so all SQLAlchemy mapper relationships
  resolve before ORM queries in the scheduler context

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 14:21:29 -05:00
chihlasm
36e1335a00 refactor: extract PROCEDURAL_TREE_TYPES constant and add negative tree_type test
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 10:54:39 -05:00
chihlasm
d75e6f78e1 feat: add maintenance tree_type with db migration and tests
- Expand ck_trees_tree_type CHECK constraint to include 'maintenance'
- Add 'maintenance' to TreeType Literal in schemas
- Treat maintenance trees as procedural in can_publish_tree validation
- Alembic migration 0f1ca2af3647 drops and recreates the constraint
- Two integration tests: create and filter by tree_type=maintenance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-17 10:35:31 -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
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
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
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
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
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
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
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
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
Michael Chihlas
7b0788712d Fix database migrations for Railway deployment
- Add InviteCode model import to alembic env.py
- Derive DATABASE_URL_SYNC from DATABASE_URL as a property
  so it uses the same Railway-provided connection string

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 00:53:55 -05:00
Michael Chihlas
20c4c40a1f Add invite code registration system for beta
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>
2026-02-01 00:08:06 -05:00
Michael Chihlas
f6bc4b0e40 Add Railway deployment configuration
- Add Dockerfiles for backend (FastAPI) and frontend (nginx)
- Add railway.toml configs with health checks
- Add .dockerignore files for optimized builds
- Update config.py to auto-convert Railway DATABASE_URL format
- Add FRONTEND_URL env var for production CORS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:03:26 -05:00
Michael Chihlas
06cc83e3fe Rebrand: Rename project from Apoklisis to Patherly 2026-01-31 20:08:17 -05:00
Michael Chihlas
cd10ecd42c Complete Phase 2: Frontend implementation with React + TypeScript
Frontend Features:
- React 18 + Vite + TypeScript + Tailwind CSS + Zustand
- JWT authentication with automatic token refresh
- Tree library with search and category filtering
- Full tree navigation (decision/action/solution nodes)
- Session management with notes and completion
- Session history with export (Markdown/Text/HTML)
- ErrorBoundary for graceful error handling

Backend Fixes:
- CORS: Added port 5174 to allowed origins
- Sessions: Fixed JSONB datetime serialization (mode='json')

Documentation:
- Updated PROGRESS.md with Phase 2 completion
- Updated 03-DEVELOPMENT-ROADMAP.md with checked items
- Added PHASE-2.5-PERSONAL-BRANCHING.md spec

Seed Data:
- Added backend/scripts/seed_data.py with Password Reset tree

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 22:42:22 -05:00
Michael Chihlas
7d96807fb1 Add production logging, datetime fixes, and session tests
DateTime Timezone Handling (Critical Bug Fix):
- Updated all models to use DateTime(timezone=True) for PostgreSQL
- Changed datetime defaults to lambda: datetime.now(timezone.utc)
- Fixed mixing of timezone-aware and timezone-naive datetime objects
- Resolved Internal Server Errors in session completion endpoint
- Affected models: User, Team, Tree, Session, Attachment

Production Logging System:
- Created logging_config.py with structured logging setup
- Added log rotation (10MB files, 10 backups) for production
- Implemented RequestLoggingMiddleware with correlation IDs
- Added ErrorLoggingMiddleware for comprehensive error tracking
- Integrated logging into main.py application startup
- Supports dev/prod modes with appropriate log levels

Integration Tests - Session Workflow:
- Created test_sessions.py with 12 comprehensive tests
- Session lifecycle: create, update, complete
- Session export in multiple formats (markdown, text, HTML)
- Error handling and authorization checks
- Added pytest.ini with coverage configuration
- Added requirements-dev.txt with pytest dependencies

Following 2026 FastAPI best practices for timezone handling and structured logging.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 20:39:09 -05:00
Michael Chihlas
52e8190211 Initial commit: Backend API Phase 1a complete
- FastAPI backend with JWT auth
- PostgreSQL database schema
- Trees and Sessions CRUD APIs
- Export functionality (Markdown, Text, HTML)
- Docker setup for local development
- Alembic migrations
2026-01-22 14:38:53 -05:00