Commit Graph

394 Commits

Author SHA1 Message Date
Michael Chihlas
ecb9dd77dc docs: update CLAUDE.md for PSA integration phase and add ConnectWise reference docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 01:44:57 -04:00
Michael Chihlas
7f3f054583 fix(psa): move CW clientId to server config, remove from user input
ClientId is a product-level GUID registered at developer.connectwise.com,
not per-MSP. Moved to settings.CW_CLIENT_ID env var. MSPs now only
provide site URL, company ID, public key, and private key.

Also added newline handling note to post_note() — CW Developer Guide
states \n is unsupported in JSON bodies. Needs sandbox testing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 00:15:04 -04:00
Michael Chihlas
db305f54e7 feat(psa): add Member Mapping tab with auto-match and manual assignment
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:53:02 -04:00
Michael Chihlas
f6ce135b22 feat(psa): attribute posted notes to mapped CW member
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:46:35 -04:00
Michael Chihlas
1771577732 feat(psa): add member mapping CRUD and auto-match endpoints
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:46:21 -04:00
Michael Chihlas
540208a923 feat(psa): implement list_members in ConnectWise provider with cache
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:45:14 -04:00
Michael Chihlas
eeee94f74b feat(psa): add PsaMemberMapping model and migration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:45:00 -04:00
Michael Chihlas
0e2aaff571 feat(psa): add Post History tab placeholder to Integrations page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:39:54 -04:00
Michael Chihlas
74875d74e1 feat(psa): add Update Ticket modal with note posting and status update
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:39:49 -04:00
Michael Chihlas
5ade3be44e feat(psa): add PSA post preview, post-to-ticket, and post history endpoints
Three new session-scoped endpoints for posting session documentation
to linked PSA tickets:

- GET /sessions/{id}/psa-post/preview — generates PSA-formatted content,
  fetches ticket details and available statuses, counts previous posts
- POST /sessions/{id}/psa-post — posts note to CW ticket with optional
  status update, logs all actions in psa_post_log audit trail
- GET /sessions/{id}/psa-posts — returns post history for the session

New schemas: PsaPostRequest, PsaPostResponse, PsaPreviewResponse,
PsaPostLogResponse.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:31:11 -04:00
Michael Chihlas
74ee5009c2 feat(psa): implement post_note and update_ticket_status in CW provider
Replaces NotImplementedError stubs with working implementations:
- post_note maps note_type to CW flag fields (internalAnalysisFlag,
  resolutionFlag, detailDescriptionFlag) with appropriate visibility
  and notification settings
- update_ticket_status uses CW JSON Patch format to update status

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:28:46 -04:00
Michael Chihlas
7059969d05 feat(psa): add PsaPostLog model and migration
Audit trail for notes posted to PSA systems. Tracks session ID,
ticket ID, note type, content, status (success/failed), and any
status changes made alongside the note post.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:28:21 -04:00
Michael Chihlas
dcf8bce2bf feat(psa): upgrade ticket picker with search and fix lookup/link separation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:14:56 -04:00
Michael Chihlas
88495b10f0 feat(psa): add in-memory TTL cache for board statuses
Add PSACache class with get/set/invalidate/clear operations and TTL expiry.
Board statuses are cached for 1 hour in the provider.
Cache is cleared when a PSA connection is re-tested.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:07:08 -04:00
Michael Chihlas
c1da853d01 feat(psa): add ticket search and status API endpoints
Add three new endpoints under /integrations/psa:
- GET /tickets/search: search CW tickets with query, board_id, status_id filters
- GET /tickets/{ticket_id}: fetch a single ticket by ID
- GET /tickets/{ticket_id}/statuses: get available statuses for a ticket's board

Add PSATicketSearchResult and PSATicketStatusItem schemas.
All endpoints require engineer_or_admin auth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:07:03 -04:00
Michael Chihlas
5a35c933e0 feat(psa): implement search_tickets, get_ticket_statuses, list_companies in CW provider
Implement all remaining NotImplementedError stubs in ConnectWiseProvider:
- search_tickets: query by summary with board_id, status_id, include_closed filters
- get_ticket_statuses: fetch statuses for a service board
- list_companies: list companies with optional status filter
- get_company: fetch a single company by ID
- get_ticket_configurations: fetch configs attached to a ticket
- Extract shared _map_ticket helper to reduce duplication

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 23:06:57 -04:00
Michael Chihlas
b76864a892 feat(psa): add ticket picker modal and session header ticket link indicator
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:56:21 -04:00
Michael Chihlas
7eaab77daa feat(psa): add ticket link/unlink endpoint for sessions
PATCH /sessions/{id}/ticket-link validates ticket exists in ConnectWise
before linking, supports unlinking by sending null, and returns ticket
details on success.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:45:10 -04:00
Michael Chihlas
5bcaf6a9d4 feat(psa): add psa_ticket_id and psa_connection_id to sessions
Add columns to link sessions to PSA tickets and connections. Includes
migration 059, model relationship, and response schema fields.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:45:04 -04:00
Michael Chihlas
2a53f48d69 feat(psa): implement get_ticket in ConnectWise provider
Replace NotImplementedError stub with real implementation that fetches
a ticket by ID via CW REST API and maps it to PSATicket.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:44:58 -04:00
Michael Chihlas
ad9d4271d6 feat(psa): add Integrations page with connection management UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:14:50 -04:00
Michael Chihlas
08e1b4bf38 feat: add PSA connection API endpoints with RBAC and tests
Five endpoints under /integrations/psa/connections:
- GET (any auth user), POST/PUT/DELETE/test (owner+ only)
- Create tests CW connection before saving; update re-tests on cred change
- Credentials decrypted only for masked hints in responses
- Three CI-safe tests: empty GET, engineer 403, delete 404

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:06:48 -04:00
Michael Chihlas
910b3c4aef feat: add Pydantic schemas for PSA connection CRUD
PsaConnectionCreate, PsaConnectionUpdate, PsaConnectionResponse,
and PsaConnectionTestResponse — registered in schemas __init__.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:53:57 -04:00
Michael Chihlas
2086ecb5ea feat(psa): add ConnectWiseProvider with test_connection + provider registry
ConnectWiseProvider implements PSAProvider with test_connection() that
calls GET /system/info to verify credentials and connectivity. All other
methods raise NotImplementedError with slice references for future work.

Provider registry (get_provider_for_account) looks up the account's
PsaConnection, decrypts stored credentials, and instantiates the
correct provider. Currently supports connectwise only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:52:23 -04:00
Michael Chihlas
fdaea49d3b feat(psa): add ConnectWise HTTP client with auth, URL resolution, pagination, retry
Implements ConnectWiseClient in services/psa/connectwise/client.py with:
- API key auth (Base64 companyId+publicKey:privateKey) + clientId header
- Accept header pinned to CW API version 2025.16
- Dynamic base URL resolution via /login/companyinfo (cloud vs on-premise)
- SSRF prevention: validates against known CW domains, rejects private IPs
- Retry with exponential backoff for timeouts and 5xx errors
- 429 rate limit handling with Retry-After header respect
- Error mapping: 401/403/404/429/5xx to typed PSA exceptions
- Paginated GET with while-loop pattern (max 1000 per page)
- JSON Patch array format for PATCH requests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:51:49 -04:00
Michael Chihlas
5323768de6 feat(psa): add PsaConnection model and migration 058
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:49:19 -04:00
Michael Chihlas
086e4c6d59 feat(psa): add Fernet credential encryption with HKDF key derivation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:48:09 -04:00
Michael Chihlas
d2edb9e3ce feat(psa): add PSA abstraction layer — base types, exceptions, abstract interface
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:46:12 -04:00
Michael Chihlas
1e3b6c0784 docs: add ConnectWise PSA integration implementation plan
5-slice plan covering foundation (abstraction layer, encryption,
connection CRUD, frontend), ticket linking, ticket search, update
ticket modal, and member mapping. Slice 1 has full task-level detail;
slices 2-5 are outlined for iterative planning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 21:21:56 -04:00
Michael Chihlas
80e094215f docs: add ConnectWise PSA integration design spec
Comprehensive design for ConnectWise PSA integration covering
credential management, service ticket integration, session-to-ticket
notes, and callback webhooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 20:31:03 -04:00
chihlasm
d4dbf44781 feat: Script Generator Phase 1+2 — backend, engine, API, frontend, template editor, parameter detector
Complete Script Generator feature including:

Backend:
- ScriptCategory, ScriptTemplate, ScriptGeneration models
- ScriptTemplateEngine with substitution, filters, sanitization
- CRUD + share API endpoints with permission checks
- Integration tests for permissions and sharing
- Migration 057 with AD User Management seed templates

Frontend — Script Library:
- Browse templates with category tabs and search
- Configure pane with parameter form and script generation
- Script preview with live substitution and copy/download
- scriptGeneratorStore Zustand store

Frontend — Template Editor:
- Full CRUD form with metadata, script body (Monaco Editor), parameters
- ParameterSchemaBuilder with visual builder + JSON toggle
- ScriptManagePage with routing and nav link

Frontend — Parameter Detector:
- Client-side PowerShell parameter detection engine
- Detects script-level param() blocks and variable assignments
- Type inference from PS type annotations and value patterns
- ParameterDetectorStepper one-by-one review UI with accept/skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 20:18:59 -04:00
chihlasm
83b13fcd26 polish: use 'step' instead of 'node' in procedural editor validation hints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
45fb468db3 feat: add validation summary and Fix with AI to procedural editor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
f9315d2f60 feat: add data-step-id anchor to StepList for validation scroll-to
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
b89d0859d4 feat: add validation state and validate() to proceduralEditorStore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
b804c63754 fix: validation summary click-to-select now opens node editor panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 23:32:52 -04:00
chihlasm
d989fabd90 Merge feat/kb-accelerator into main 2026-03-12 17:29:07 -04:00
Michael Chihlas
cfe112ac43 docs: add landing page assets and polish landing CSS
Add landing page .docx export, HTML mockup, docx generator script,
and refine landing page CSS formatting/spacing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:28:49 -04:00
chihlasm
042a12b190 feat: add landing page with beta signup + raise KB node limit to 100
Landing page at /landing with full marketing content: hero, features,
pricing, testimonials, and beta email signup form. Beta signups email
beta@resolutionflow.com via new public endpoint. Unauthenticated users
redirect to landing instead of login. Also raises KB Accelerator node
limit from 50 to 100 to accommodate dense troubleshooting articles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 00:23:29 -04:00
chihlasm
92c86cab80 fix: handle object-shaped validation errors in KB commit error toast
The commit endpoint returns {message, validation_errors} when
validation fails, but the error handler was passing the whole object
to toast.error(), crashing React with "Objects are not valid as a
React child".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:56:45 -04:00
chihlasm
458c2d9cab fix: prevent circular parent_node_id in KB troubleshooting import
AI-generated trees can have circular next_node_id references (e.g.,
node A → B → A). The parent mapping now checks for cycles before
assigning parent_node_id, preventing FK deadlocks during insert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:46:49 -04:00
chihlasm
efafcff4b2 fix: topological insert for KB import nodes to satisfy parent FK
Nodes with parent_node_id references were inserted in a single batch,
causing FK violations when children were inserted before their parents.
Now inserts roots first, flushes, then children in subsequent passes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:41:25 -04:00
chihlasm
03390ed59f feat: enable Markdown (.md) file upload in KB Accelerator
Moved md from Phase 2 extensions to allowed formats, added extraction
handler (reuses txt handler), and updated plan_limits defaults to
include md for all plans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:29:51 -04:00
chihlasm
fe3c651115 fix: remove "Let AI Decide" option from KB Accelerator upload
The uploader should know their content type — auto-detection adds
complexity and currently just defaults to troubleshooting anyway.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:56:40 -04:00
Michael Chihlas
963c0da10a docs: update CLAUDE.md with Railway and node field learnings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 21:19:51 -04:00
Michael Chihlas
9495b09e72 fix: copilot node context — use title/question/description over legacy content field
_build_flow_context() was reading node.get('content') which was only
present on old KB-imported steps. Now falls back through title →
question → description → content → label so all node types (decision,
action, solution, procedural step) show correctly in the copilot context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 17:55:26 -04:00
Michael Chihlas
53b6878742 fix: KB procedural import — map step content to description field
Steps built by _build_procedural_tree() were stored under the "content"
key but StepDetail.tsx reads "description". Renamed the key so step
text and commands display correctly during session execution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 12:50:13 -04:00
Michael Chihlas
00e1e701ca fix: procedural KB import — add title field, correct step types, validation gate
- _build_procedural_tree now maps AI node types (step, action, warning) to
  valid procedural types (procedure_step, section_header, procedure_end)
- Generates 'title' field from content text — fixes "Unnamed step" in editor
- Auto-appends procedure_end step if AI didn't generate one
- Adds procedural validation gate at commit endpoint (same as troubleshooting)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 09:12:43 -04:00
Michael Chihlas
c920e825c6 fix: auto-reload on chunk load errors in ErrorBoundary
RouteError already handled stale chunk errors, but the Sentry ErrorBoundary
didn't — so errors from React lazy() imports hit the generic error UI.
Now auto-reloads with loop prevention (10s cooldown via sessionStorage).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:17:24 -04:00
Michael Chihlas
a976f16575 fix: session closure popover z-index — bypass stagger-item stacking context
The StaggerList wrapper creates per-item stacking contexts via CSS animation,
causing the absolute-positioned close popover to render behind sibling cards.
Replace StaggerList with inline stagger-item rendering so we can apply z-50
directly to the stagger-item wrapper when its popover is open.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:09:17 -04:00