87bd0b7c569691d7fa09b0fb3c0ea6d144fc13b8
First half of the WebSocket/SSE push slice. Paused mid-flight to hand
the branch to Codex for outside-voice review before stacking more
commits on top. See .ai/HANDOFF.md for the full pause context + what
to look at.
What's here:
- backend/app/core/escalation_bus.py — module-level singleton in-memory
pub/sub keyed by account_id. asyncio.Queue per subscriber with
64-event maxsize and drop-on-full semantics. Designed to be swappable
for Redis pub/sub when Railway scales past single-replica.
- backend/app/api/endpoints/session_handoffs.py — GET
/api/v1/ai-sessions/escalations/stream SSE endpoint. Auth via
require_engineer_or_admin. 25s heartbeat. Account-scoped subscribe
bound to current_user.account_id.
- backend/app/services/handoff_manager.py — dispatch_escalation_notifications
now publishes a `handoff_created` event to the bus BEFORE the email
fan-out, in a try/except so a bus failure can't block email delivery.
- backend/tests/test_escalation_bus.py — 7 unit tests, all green
standalone (0.14s). Cross-tenant isolation, drop-on-full, no-subscribers.
- backend/tests/test_handoff_manager.py — +1 dispatcher integration test
(publishes to bus, payload shape).
- backend/tests/test_session_handoffs_api.py — +2 endpoint tests (viewer
blocked, ready event handshake).
[gstack-context]
Decisions:
- SSE over WebSocket (one-way, browser EventSource semantics, fewer
moving parts behind Railway proxy)
- In-memory bus over Redis for v1 pilot (3 MSPs, single replica)
- Drop-on-full subscriber queue rather than back-pressure publishers
- Bus publish ahead of email send, both wrapped in try/except so
neither can break handoff creation
- Frontend will be a fetch-based ReadableStream reader matching the
existing streamDocumentation pattern, not native EventSource
(custom-header auth)
Remaining (post-Codex):
- Frontend SSE subscription in EscalationQueue.tsx (slide-in,
reconnect, tab-title flash, prefers-reduced-motion)
- Magic-moment handoff-context screen
- Re-run the full backend test suite to verify the SSE +
dispatcher integration tests (bus units already green standalone)
Tried:
- Running the full test suite repeatedly without xdist; the per-test
DROP SCHEMA + recreate fixture made wall-clock prohibitive when
multiple stale runs collided on the same Postgres test schema.
Resolution: -n auto next time.
[/gstack-context]
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix: replace all remaining old brand tokens (text-brand-dark, border-brand-border, bg-white opacity)
ResolutionFlow
Stop writing ticket notes. Start generating them.
ResolutionFlow is an AI-powered troubleshooting platform for MSP professionals. Engineers follow guided flows while an AI copilot assists — and documentation writes itself as a byproduct of the work.
Production: resolutionflow.com
Quick Start
# Prerequisites: Docker, Python 3.11+, Node.js 20+
# Start PostgreSQL
docker start patherly_postgres
# Backend
cd backend
source venv/bin/activate
pip install -r requirements.txt
alembic upgrade head
uvicorn app.main:app --reload
# Frontend (separate terminal)
cd frontend
npm install
npm run dev
- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/api/docs
See DEV-ENV.md for full environment setup (devserver, Docker, CORS).
Features
FlowPilot AI Copilot
Like having a senior engineer on every call. FlowPilot guides troubleshooting decisions, suggests next steps with context-aware intelligence, and automatically captures documentation as a byproduct of the session.
- Confidence-tiered model routing (fast responses for simple steps, deeper reasoning for complex decisions)
- AI-generated ticket summaries and session documentation
- Standalone assistant chat with RAG for open-ended troubleshooting
- Knowledge Flywheel: AI analyzes completed sessions and proposes new flows automatically
Guided Flows
- Troubleshooting Flows — Decision trees with branching paths for diagnosing issues
- Procedural Flows (Projects) — Step-by-step checklists for onboarding, migrations, deployments
- Maintenance Flows — Scheduled recurring tasks with batch execution across multiple targets
- Visual Flow Editor with drag-and-drop canvas, undo/redo, markdown support
- AI Flow Builder — describe what you need, get a complete flow generated
Auto-Documentation
Every session generates timestamped, detailed notes formatted for your PSA. Engineers never write another ticket note.
- Export to Markdown, plain text, or HTML
- Sensitive data redaction
- One-click push to ConnectWise PSA tickets
ConnectWise PSA Integration
- Post session documentation directly to ConnectWise tickets as internal notes
- Pull ticket details and client context into FlowPilot sessions
- Member mapping between ResolutionFlow and ConnectWise users
- Credentials encrypted at rest (Fernet), stored per-team
Team & Knowledge Management
- Role-based access (super_admin, team_admin, engineer, viewer)
- Shared flow library with categories, tags, folders, full-text search
- Step Library — reusable troubleshooting steps with ratings and reviews
- Session sharing via link (authenticated and public views)
- Escalation workflow with AI-enhanced briefing packages
- Flow proposals from AI analysis (review queue for team leads)
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite, Tailwind CSS v4 |
| State | Zustand (immer + zundo for undo/redo) |
| Routing | React Router v7 |
| Canvas | @xyflow/react (React Flow) + dagre |
| Backend | Python FastAPI, async SQLAlchemy 2.0 + asyncpg |
| Database | PostgreSQL 16 |
| Migrations | Alembic (75+ migrations) |
| Auth | JWT (python-jose) + bcrypt, refresh token rotation |
| AI | Anthropic Claude API (tiered model routing) |
| Embeddings | Voyage AI (semantic search) |
| Scheduling | APScheduler 3.x (async) |
| Analytics | PostHog |
| Hosting | Railway (auto-deploy on push to main) |
Project Structure
patherly/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI entry point
│ │ ├── api/endpoints/ # Route handlers (35+ endpoints)
│ │ ├── core/ # Config, database, permissions, security
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ └── services/psa/ # PSA provider abstraction layer
│ ├── alembic/ # Database migrations
│ └── tests/ # Integration tests (100+)
├── frontend/
│ ├── src/
│ │ ├── components/ # UI components by domain
│ │ ├── pages/ # Page components
│ │ ├── store/ # Zustand stores
│ │ └── types/ # TypeScript interfaces
├── docs/ # Design docs, plans, ConnectWise reference
├── brand-assets/ # SVGs, brand guide
├── CLAUDE.md # AI assistant project context
├── CURRENT-STATE.md # Detailed feature status
└── CHANGELOG.md # Release history
Running Tests
# Backend integration tests
cd backend
pytest --override-ini="addopts="
# Frontend build (stricter than tsc --noEmit)
cd frontend
npm run build
Documentation
| Document | Purpose |
|---|---|
| CLAUDE.md | Full project context for AI-assisted development |
| CURRENT-STATE.md | Detailed feature status |
| 03-DEVELOPMENT-ROADMAP.md | Development roadmap |
| UI-DESIGN-SYSTEM.md | Design system (Slate & Ice) |
| DEV-ENV.md | Development environment setup |
| CHANGELOG.md | Release history |
License
Proprietary. All rights reserved.
Description
Troubleshooting decision tree application for MSP engineers - automatically generates professional documentation from guided diagnostic workflows
Languages
Python
54.7%
TypeScript
43.5%
HTML
1.1%
CSS
0.6%