Files
resolutionflow/CLAUDE.md
chihlasm 8e2332bc51 docs: update CLAUDE.md with lessons 78-82 and current state
- Update phase to Go-to-Market Validation (Pre-PMF)
- Update in-progress and recently completed sections
- Lesson 78: Landing page subtitle branding
- Lesson 79: Custom modal mobile-responsive pattern
- Lesson 80: TopBar search collapses to icon on mobile
- Lesson 81: No transition: all in CSS
- Lesson 82: Bun PATH setup on devserver01

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:50:55 +00:00

32 KiB
Raw Blame History

CLAUDE.md - Patherly / ResolutionFlow Project Context

Last Updated: March 21, 2026


Project Overview

Patherly (user-facing brand: ResolutionFlow) is a SaaS product for MSP professionals. It provides troubleshooting decision trees that guide engineers through proven troubleshooting paths, capture decisions and notes, and generate professional ticket documentation.

Target Market: MSP companies — IT service providers managing infrastructure and support for multiple clients.

SaaS Context: Multi-tenant design — teams represent MSP companies, trees shared within teams, tiered access (super_admin, team_admin, engineer, viewer).

Branding

Context Name Used
Repository / directory / database / Docker patherly / patherly_postgres
Backend, frontend UI, production URLs ResolutionFlow
  • Design: Dark glassmorphism with ice-cyan accent gradient (#06b6d4#22d3ee). Charcoal backgrounds, frosted-glass cards with backdrop-filter: blur(), orchestrated page-load animations, bold display typography. Design doc: docs/plans/2026-03-03-aesthetic-redesign-design.md
  • Fonts: Bricolage Grotesque (font-heading, headings/titles), IBM Plex Sans (font-sans, body text), JetBrains Mono (font-label, labels/badges/timestamps) — loaded via Google Fonts
  • Logo: Inline SVG in BrandLogo.tsx (decision-tree icon with cyan gradient). Wordmark: "Resolution" in text-foreground + "Flow" in text-gradient-brand
  • Brand assets: brand-assets/ (source SVGs + brand-guide.html), frontend/src/assets/brand/ (app assets), frontend/public/icons/ (favicon)
  • CSS utilities: text-gradient-brand, bg-gradient-brand, bg-gradient-brand-hover (defined in index.css via @theme). Glass utilities: .glass-card (interactive, scale(1.02) hover), .glass-card-static (no hover transform), .active-glow (breathing cyan shadow)
  • Layout: App shell with persistent sidebar + top bar + main content (CSS Grid). Two fixed atmosphere orbs (cyan top-right, purple bottom-left) behind the shell for ambient glow. See UI-DESIGN-SYSTEM.md
  • Navigation: Sidebar nav with type sub-items (All Flows → Troubleshooting / Projects / Maintenance). Pinned flows section for quick access. NO workspace switcher. See UI-DESIGN-SYSTEM.md
  • Terminology: User-facing label is "Flows" (not "Trees"). Procedural flows are called "Projects" in the UI. Maintenance flows are called "Maintenance" in the UI. tree_type column values unchanged in DB.
  • Rebrand guide: REBRAND-IMPLEMENTATION-GUIDE.md

Component styling rules:

  • Primary buttons: bg-gradient-brand (cyan 135deg) with shadow-lg shadow-primary/20, hover opacity-0.9, active scale(0.97)
  • Secondary buttons: bg-[rgba(255,255,255,0.04)] with border-[rgba(255,255,255,0.06)], hover brightens border
  • Active nav items: bg-primary/10 background + 3px left cyan gradient accent bar
  • Stat values: use text-gradient-brand for highlighted metrics
  • Status colors: emerald-400 (success), amber-400 (in-progress), rose-500 (error/critical)
  • Category dots: 8px colored circles using the category color palette
  • Tags/badges: font-label (JetBrains Mono), small rounded chips with bg-card border-border
  • Cards: .glass-card (interactive) or .glass-card-static (non-interactive) — semi-transparent bg with backdrop-filter: blur(16px), border-radius: 16px
  • Section labels: font-label text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground

When adding new pages/components: use "ResolutionFlow" branding, ice-cyan gradient accent theme, .glass-card / .glass-card-static containers, text-foreground/text-muted-foreground hierarchy. Primary actions use bg-gradient-brand. Pages render inside the app shell (CSS Grid: topbar + sidebar + main). Use "Flows" not "Trees" in all user-facing text; use "Projects" not "Procedures" for procedural flows. Reference UI-DESIGN-SYSTEM.md for layout patterns, navigation, and component specs.

Implementation Principles

  • Prefer correct architecture over minimal diff
  • If two approaches exist, implement the one that scales, not the one that's faster to write
  • Flag any "simpler approach" tradeoffs for product owner review before proceeding

Current State

  • Phase: Go-to-Market Validation (Pre-PMF)
  • Backend: Complete (35+ API endpoints, 100+ integration tests)
  • Frontend: Core features complete, Tree Editor functional
  • Database: PostgreSQL with Docker, 75 migrations
  • Detailed status: CURRENT-STATE.md

What's In Progress

  • Go-to-market validation: shadow MSP engineers, get product in front of real users
  • Landing page polish: mobile responsiveness, design audit fixes
  • Remaining open issues: #66 Templates + Import/Export, #60 Recurring Issue Detection, #58 Step Feedback Flag

Recently Completed

  • Landing page design audit: hamburger menu, Privacy/Terms pages, branding alignment, mobile responsive modals, section spacing
  • Root directory cleanup: archived 9 completed docs, tracked marketing assets
  • GitHub issues triage: closed 10 stale issues (6 completed, 4 deferred)
  • FlowPilot Phase 2: PSA integration, escalation handoff, session pause/resume, mid-session ticket linking
  • Step Library Foundation
  • AI chat session conclusion: outcome tracking, AI-generated ticket summaries, resume flow
  • Survey completion: email-to-self, thank-you page, admin read/unread/archive/delete management
  • Survey system: public survey page, admin invite tracking, response viewer with CSV export
  • Email verification: tokens, banner, admin toggle (platform setting)
  • AI assistant: in-session copilot panel, standalone chat with RAG
  • Slate & Ice aesthetic redesign: glassmorphism, brand fonts, orchestrated animations
  • Account management: profile settings, delete/leave/transfer, chat retention
  • Maintenance flows: batch session launch, saved target lists, APScheduler scheduling

Tech Stack

Backend

  • Framework: Python FastAPI
  • Database: PostgreSQL 16 (async via SQLAlchemy 2.0 + asyncpg)
  • Migrations: Alembic
  • Auth: JWT (python-jose) + bcrypt, refresh token rotation (JTI-based)
  • Validation: Pydantic v2
  • Scheduling: APScheduler 3.x (async, in-process with FastAPI lifespan) + croniter + pytz

Frontend

  • Framework: React 19 + Vite + TypeScript
  • Styling: Tailwind CSS v4 (@tailwindcss/vite plugin, CSS-only config in index.css) — dark-first with ice-cyan gradient accents (see Branding section)
  • State: Zustand (with immer + zundo for undo/redo)
  • Routing: React Router v7
  • API Client: Axios with token refresh interceptor
  • Icons: Lucide React

Key Project Structure

patherly/
├── backend/
│   ├── app/
│   │   ├── main.py                 # FastAPI entry point
│   │   ├── api/endpoints/          # Route handlers (auth, trees, sessions, admin, steps, survey, copilot, assistant_chat, psa_connections)
│   │   │   ├── flow_proposals.py   # Knowledge Flywheel review queue CRUD
│   │   │   └── flowpilot_analytics.py # FlowPilot dashboard metrics
│   │   ├── api/deps.py             # Auth dependencies (includes require_team_admin)
│   │   ├── api/router.py           # Route registration
│   │   ├── core/                   # config, database, permissions, security, audit, rate_limit
│   │   ├── models/                 # SQLAlchemy models (includes FlowProposal)
│   │   ├── schemas/                # Pydantic schemas
│   │   ├── services/psa/           # PSA provider abstraction (base, connectwise/, cache, encryption, registry, types)
│   │   ├── services/knowledge_flywheel.py        # AI session analysis → flow proposals
│   │   ├── services/knowledge_flywheel_scheduler.py # APScheduler job for batch analysis
│   │   └── services/knowledge_gap_service.py     # Weak options & escalation signal detection
│   ├── alembic/                    # Database migrations (001-029+)
│   ├── scripts/                    # seed_data.py, seed_trees.py
│   └── tests/                      # pytest integration tests
├── frontend/
│   ├── src/
│   │   ├── api/                    # Axios client + endpoint modules
│   │   ├── components/             # common, layout, dashboard, tree-editor, session, procedural, procedural-editor, library, step-library, ui, flowpilot
│   │   ├── hooks/                  # usePermissions, useSessionTimer, useKeyboardShortcuts
│   │   ├── pages/                  # All page components
│   │   ├── store/                  # Zustand stores (auth, treeEditor, proceduralEditor, userPreferences)
│   │   └── types/                  # TypeScript interfaces
│   └── (Tailwind v4: CSS-only config in src/index.css)
├── docs/plans/archive/             # Archived design/impl docs (pre-March 2026)
├── CLAUDE.md                       # This file
├── CURRENT-STATE.md                # Detailed feature status
├── LESSONS-LEARNED.md              # (Deprecated — consolidated into CLAUDE.md)
└── docs/plans/                     # Design docs & implementation plans

Environment Variables

Backend (backend/.env)

APP_NAME=ResolutionFlow
DEBUG=true
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/patherly
DATABASE_URL_SYNC=postgresql://postgres:postgres@localhost:5432/patherly
SECRET_KEY=<openssl rand -hex 32>
ACCESS_TOKEN_EXPIRE_MINUTES=5
REFRESH_TOKEN_EXPIRE_DAYS=7
REQUIRE_INVITE_CODE=true

Frontend (frontend/.env.local - optional)

VITE_API_URL=http://localhost:8000

ConnectWise PSA Integration

ResolutionFlow integrates with ConnectWise PSA (formerly Manage) as the primary PSA integration. All ConnectWise API reference materials live in docs/connectwise/.

Best Practices Documentation

Official ConnectWise developer guides live in docs/connectwise/best-practices/. Read these BEFORE implementing any CW API integration code:

  • PSA-API-Requests.md — HTTP methods, response codes, condition query syntax, PATCH format, URL encoding, partial responses, custom fields. READ FIRST.
  • PSA-Callbacks.md — Callback type/level matrix, retry behavior, URL parameter gotcha, HMAC signature verification.
  • PSA-Pagination.md — Navigable vs Forward-Only pagination, Link headers, while-loop pattern.
  • PSA-Service-Tickets.md — Ticket field philosophy, recommended field mappings.
  • PSA-Versioning.md — Pin API version via Accept header. Use application/vnd.connectwise.com+json; version=2025.16.
  • PSA-Cloud-URL-Formatting.md — Dynamic base URL construction via /login/companyinfo/{companyId}.
  • Bundled-Requests.md — Batch multiple API calls into one request via /system/bundles.
  • PSA-Markdown.md — Ticket notes support markdown. Format session documentation output accordingly.
  • PSA-Company-Synchronization.md — Filter companies by Status/Type for mapping UI.
  • PSA-Data-Protection.md — Security role model, request minimal permissions (MY not ALL).

Reference Files (read in this order)

  1. docs/connectwise/CONNECTWISE-API-REFERENCE.md — Read FIRST. Quick reference covering auth patterns, tiered endpoint map, key field mappings, and integration architecture flows.
  2. docs/connectwise/connectwise-psa-resolutionflow-reference.json — Extracted OpenAPI 3.0.1 spec (v2025.16) with only the 670 endpoints and 342 schemas relevant to ResolutionFlow. Use for exact field types, request/response shapes, and parameter details.
  3. docs/connectwise/connectwise-psa-openapi-full.json — Complete ConnectWise PSA OpenAPI spec (1838 endpoints, 842 schemas). Only consult if you need an endpoint outside the extracted subset.

Integration Architecture

  • Session → Ticket Notes: Post auto-generated session documentation to ConnectWise tickets as internal analysis notes via POST /service/tickets/{id}/notes
  • Ticket Context → Session Runner: Pull ticket details, company info, and attached configurations to give FlowPilot AI real-world context
  • Callbacks: Register webhooks via /system/callbacks for real-time ticket event notifications to suggest relevant Flows

Key Implementation Rules

  • Auth: API Key auth (Base64 of companyId+publicKey:privateKey) + clientId header on every request
  • clientId is server-side config (CW_CLIENT_ID in config.py) — identifies the ResolutionFlow app, NOT per-tenant. Per-connection credentials: company_id, public_key, private_key, server_url
  • All PSA integration code in services/psa/ — provider pattern with PSAProvider abstract base class, ConnectWiseProvider implementation, PsaProviderRegistry for multi-PSA dispatch
  • PSA endpoints in api/endpoints/psa_connections.py — connection CRUD, ticket ops, member mapping
  • Credentials encrypted at rest via services/psa/encryption.py (Fernet)
  • Each MSP tenant provides their own CW credentials — ResolutionFlow stores these per-team, never per-user
  • Design for the Autotask integration following the same service layer pattern (future PSA)
  • In-memory TTL cache in services/psa/cache.py for board/status/priority lookups
  • Respect CW API: paginate with max 1000 per page, handle retries gracefully

Development Commands

# Start PostgreSQL
docker start patherly_postgres

# Backend (from backend/)
source venv/bin/activate        # Linux/Mac
# .\venv\Scripts\Activate       # Windows
uvicorn app.main:app --reload

# Frontend (from frontend/)
npm run dev

# Run tests (from backend/)
pytest --override-ini="addopts="

# First time only: create test database
docker exec -it patherly_postgres psql -U postgres -c "CREATE DATABASE patherly_test;"

# Frontend build (IMPORTANT: stricter than tsc --noEmit — always use as final check)
cd frontend && npm run build

# Database migrations
cd backend && alembic upgrade head
alembic revision --autogenerate -m "Description" --rev-id=NNN  # NNN = next sequential number

# Access PostgreSQL
docker exec -it patherly_postgres psql -U postgres -d patherly

# Seed data
cd backend && pip install httpx && python -m scripts.seed_trees

# CI/CD debugging
gh run list --limit 5                          # Recent CI runs
gh run view <id> --log-failed                  # Failed job logs
gh run watch <id> --exit-status                # Watch run until complete
gh run view <id> --json jobs --jq '.jobs[] | {name: .name, conclusion: .conclusion}'

URLs

Test Users (seeded via scripts/seed_test_users.py)

  • All share password: TestPass123!
  • admin@resolutionflow.example.com (super_admin), teamadmin@resolutionflow.example.com (team_admin), engineer@resolutionflow.example.com (engineer), pro@resolutionflow.example.com (solo pro)

Critical Lessons Learned

Lessons 1-40 archived to docs/LESSONS-ARCHIVE.md — fixes are baked into the codebase. Consult if you hit a regression.

Active Lessons (41+)

41. Assistant chat uses local React state, not Zustand: AssistantChatPage.tsx uses useState for chats, messages, input, loading. No store.

42. Public pages use raw fetch(), not apiClient: Survey, shared sessions, and no-auth pages use fetch() with full URL. apiClient requires auth tokens.

43. Adding new email types: Add static async method to EmailService in core/email.py. Fire-and-forget from endpoints (log errors, don't fail).

44. AI Chat Builder is flow-type-aware: ai_chat_service.py dispatches by flow_type. Troubleshooting: [TREE_UPDATE] markers. Procedural: [STEPS_UPDATE] markers. Both support [METADATA].

45. Intake form field schema: Uses variable_name and field_type (NOT name and type).

46. CreateFlowDropdown uses AIPromptDialog: Opens prompt modal, starts AI session, generates flow, navigates to editor with { state: { aiPanelOpen: true, sessionId } }.

47. Editor-Embedded Flow Assist: EditorAIPanel (320px side panel) + useEditorAI hook. Ghost nodes use _suggestion: true flag. Actions route to model tiers via settings.get_model_for_action(). Delta responses use [DELTA]...[/DELTA] markers.

48. Tree orphan validation uses dynamic root ID: Orphan check compares against state.treeStructure?.id (NOT hardcoded 'root').

49. Full-stack features — verify both ends: Check the full data flow: schema → endpoint → API client → hook → store → UI.

50. Anthropic SDK retry: Set max_retries=1 to fail fast. Default max_retries=2 can take 3× timeout.

51. AI model tier routing: Use settings.get_model_for_action(action_type). Model IDs: use alias form (claude-sonnet-4-6).

52. Mobile scroll-to-top: Use ref.current.scrollIntoView(), not window.scrollTo(). Trigger via useEffect.

53. Flex height chain: Every ancestor must be a flex container for flex-1 to work. Missing flex class collapses React Flow to 0 height.

54. React Flow CSS in Tailwind v4: Import in index.css, not component JS. Override dark theme using --xy-* CSS custom properties.

55. App shell height chain: Every wrapper between .main-content and canvas needs flex + flex-1 + min-h-0 or h-full.

56. Railway backend service name is patherly: Production DB name is railway. Public Postgres proxy: interchange.proxy.rlwy.net:45797.

57. Node field priority: titlequestiondescriptioncontentlabel. See copilot_service.py.

58. scriptGeneratorStore.generate() optional param: Always wrap: onClick={() => generate()}, never onClick={generate}.

59. ConnectWise clientId is server-side config: Set in config.py as CW_CLIENT_ID. Per-connection: company_id, public_key, private_key, server_url.

60. Dockerfile build args for Vite env vars: Any new VITE_* or VITE_PUBLIC_* env var must be added as ARG + ENV in frontend/Dockerfile for Railway deploys. Railway env vars are runtime-only unless explicitly passed through as Docker build args. Without this, import.meta.env.VITE_* resolves to undefined in production builds.

61. Procedural sessions auto-start on page load: ProceduralNavigationPage calls startSession() immediately in loadTree() — there is no intake form screen or "Start" button. Variables are filled inline during execution. Troubleshooting flows DO have a start screen with ticket/client fields. Don't write tests or UI that assume a Start button on procedural flows.

62. Playwright strict mode — scope selectors to avoid ambiguity: Step titles appear in both the sidebar checklist and main content heading. Use getByRole('heading', { name }) for the main content, or scope with page.locator('.animate-scale-in') for command palette items. getByText() frequently matches multiple elements due to the sidebar + main content layout.

63. Node 20 required for frontend builds: Vite 7+ requires Node 20.19+. The system Node may be v18; use nvm: export NVM_DIR="$HOME/.nvm" && source "$NVM_DIR/nvm.sh" && nvm use 20. For direct binary access without nvm sourcing: PATH="/home/michaelchihlas/.nvm/versions/node/v20.19.0/bin:$PATH".

64. PostHog product analytics: Initialized via PostHogProvider in main.tsx with explicit posthog.init() + client prop pattern. Event helpers in lib/analytics.ts — use analytics.eventName(props) to track. identifyUser() called in authStore.fetchUser(), resetAnalytics() on logout. Env vars: VITE_PUBLIC_POSTHOG_KEY, VITE_PUBLIC_POSTHOG_HOST. Autocapture enabled.

65. Local Docker Compose uses resolutionflow database on port 5433: Container name is resolutionflow_postgres, database is resolutionflow (not patherly), port mapped to 5433 (not 5432). The POSTGRES_PORT env var controls this. Playwright config defaults must match: postgresql+asyncpg://postgres:postgres@127.0.0.1:5433/resolutionflow.

66. Dev environment runs on devserver01 (192.168.0.9), not localhost: Code-server runs in Docker on a LAN server. Frontend/backend are accessed via 192.168.0.9, not localhost. CORS must include http://192.168.0.9:5173 in CORS_ORIGINS and FRONTEND_URL. Frontend .env must set VITE_API_URL=http://192.168.0.9:8000. See DEV-ENV.md for full setup, Docker config, networking, and known issues.

67. Tree editor route is /trees/new: NOT /editor/new. Check router.tsx line 156 for the canonical path. Use getTreeEditorPath() from @/lib/routing when navigating programmatically.

68. APScheduler jobs need max_instances=1: Without it, overlapping scheduler runs can process the same records twice (TOCTOU race). Always set max_instances=1 on interval jobs in main.py.

69. PostgreSQL func.sum(case(...)) returns Decimal via asyncpg: Cast to int() before storing in Pydantic dict[str, Any] fields, or JSON serialization may produce unexpected types.

70. Toast library uses toast.warning() not toast.warn(): Import from @/lib/toast. Methods: success, error, warning, info. See frontend/src/lib/toast.ts.

71. Enhancement/branch_addition proposals cannot be directly approved: Backend returns 400 — they require modified_flow_data via "Edit & Publish" flow. Only new_flow proposals support direct approve.

72. ai_sessions.status column is VARCHAR(30): Must fit requesting_escalation (23 chars). If adding new status values, verify length. Migration f0aad74ea51b widened from 20→30.

73. get_db rolls back on exception: The dependency does await session.rollback() on error to prevent InFailedSQLTransaction cascade. Never remove this — without it, one failed request poisons subsequent requests on the same connection.

74. FlowPilot action bar height chain: The action bar (Resolve/Escalate/Pause) requires every ancestor from app-shell grid down to have proper flex constraints. Key fix: ViewTransitionOutlet wrapper needs flex flex-col. If action bar disappears, check height chain with DevTools getBoundingClientRect() walk.

75. Dashboard prefill auto-submits: StartSessionInput navigates to /pilot or /assistant with { state: { prefill } }. FlowPilotSessionPage auto-submits via useEffect + prefillHandledRef guard — no double-enter. AssistantChatPage does the same pattern.

76. Active session navigation guard: FlowPilotSessionPage uses useBlocker (same as TreeEditorPage) to intercept navigation during active sessions. "Pause & Leave" auto-pauses before proceeding.

77. Prefer manual Alembic migrations for targeted changes: alembic revision --autogenerate picks up drift from all tables. For single-column fixes, use alembic revision -m "desc" and write op.alter_column() manually.

78. Landing page subtitle is "AI-Powered Troubleshooting for MSPs": Not "Decision Tree Platform". This tagline appears on login, register, and the HTML <title>. The old "Decision Tree Platform" was internal jargon misaligned with user-facing branding.

79. Custom modals must be mobile-responsive: Use items-end sm:items-center (bottom-sheet on mobile, centered on desktop) and max-w-full sm:max-w-lg (full-width on mobile). The shared Modal.tsx does this correctly — custom modal implementations must follow the same pattern. See PrepareSessionModal.tsx for the fix pattern.

80. TopBar search collapses to icon on mobile: Full search bar (hidden sm:block) shows on desktop; magnifying glass icon button (sm:hidden) shows on mobile (<640px). Both open the same CommandPalette. Don't add w-full search bar without the mobile icon fallback.

81. Never use transition: all in landing.css: Specify exact properties: transition: background 0.3s, border-color 0.3s, box-shadow 0.3s, transform 0.3s, opacity 0.3s. transition: all animates layout properties and causes jank.

82. bun requires PATH setup on devserver01: export BUN_INSTALL="$HOME/.bun" && export PATH="$BUN_INSTALL/bin:$PATH". The gstack browse binary and Playwright need this. Chromium system deps: libatk1.0-0 libatk-bridge2.0-0 libcups2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2.


RBAC & Permissions

  • Role hierarchy: super_admin > team_admin > engineer > viewer
  • Team Admin: role='engineer' + is_team_admin=True + valid team_id
  • Backend deps: get_current_active_user(user, db) (any active + auto-downgrades expired trials), require_engineer_or_admin (blocks viewers), require_admin (super admin only)
  • Never use role == "admin" — use is_super_admin instead
  • Frontend: usePermissions() hook for all permission checks
  • Centralized: backend/app/core/permissions.py, frontend/src/hooks/usePermissions.ts

Design System (Slate & Ice Modern)

  • Theme: Dark glassmorphism with ice-cyan accent (#06b6d4#22d3ee). Uses .glass-card / .glass-card-static for card surfaces
  • Backgrounds: bg-background (#101114 page), glass surfaces use rgba(24, 26, 31, 0.55) with backdrop-filter: blur()
  • Cards: .glass-card (interactive, hover scale(1.02) + border/shadow upgrade) or .glass-card-static (no hover). Both have border-radius: 16px, semi-transparent bg, backdrop blur
  • Buttons: Primary: bg-gradient-brand text-[#101114] font-semibold rounded-[10px] hover:opacity-90 active:scale-[0.97]. Secondary: bg-[rgba(255,255,255,0.04)] border-[rgba(255,255,255,0.06)] text-foreground rounded-[10px]
  • Inputs: border-border bg-card text-foreground placeholder:text-muted-foreground + focus: focus:border-[rgba(6,182,212,0.3)]
  • Text: text-foreground (#f8fafc) → text-muted-foreground (#8891a0) → text-[#5a6170] (dim, for section labels/timestamps)
  • Borders: var(--glass-border) (rgba(255,255,255,0.06)) default, rgba(255,255,255,0.12) on hover
  • Hover states: Border brightens to rgba(255,255,255,0.12), shadow upgrades to --shadow-float-hover
  • Active/selected: bg-primary/10 text-foreground or cyan gradient accent bar
  • Functional colors: emerald-400 (success), rose-500 (error), amber-400 (warning), blue-400 (info). Always pair with icons, not color alone.
  • CSS variables: Glass system vars (--glass-bg, --glass-border, --glass-blur), shadow system (--shadow-float, --shadow-float-hover, --shadow-cyan-glow), easing (--ease-out-smooth) — all in index.css :root
  • Animations: Orchestrated page-load sequence (slideDown, slideInLeft, fadeInUp cascade, fadeInRight). breatheGlow on first stat card. bellWobble on notification hover. See design doc for full spec.

Frontend Patterns

  • Component guidelines: Use cn() from @/lib/utils, Lucide icons (wrap in <span> for title), modals with fixed header/footer
  • Type organization: Create in types/, export from types/index.ts, import with import type { T } from '@/types'
  • Scratchpad overlay: position: fixed, onOpenChange callback for parent padding adjustment, right-2 positioning
  • Custom step flow: CustomStepModalPostStepActionModalContinuationModal → custom step view. Key state: pendingStep, pendingContinuationNodeId, customBranchMode, branchOriginNodeId. Use findCustomStep() not findNode() for custom step UUIDs.
  • Session sharing: ShareSessionModal manages share links, SharedSessionPage renders public/account views. Helper utils in lib/sessionShare.ts. Share URLs use /shared/sessions/:token.
  • Procedural navigation: ProceduralNavigationPage handles intake forms, step-by-step execution, and resume via location.state.sessionId. Uses StepChecklist, StepDetail, ProgressBar, CompletionSummary components.
  • Routing helper: Use getTreeNavigatePath() and getTreeEditorPath() from @/lib/routing for all tree/session navigation.
  • Account section layout: AccountLayout has NO sidebar nav. Account sub-pages (categories, target-lists) are reached via link cards on AccountSettingsPage.tsx. New account pages: add route in router.tsx under account children + add a link card in AccountSettingsPage.
  • Dashboard cockpit: QuickStartPage is the FlowPilot launchpad. Components in components/dashboard/: StartSessionInput (mode picker: guided/chat), PendingEscalations, ActiveFlowPilotSessions, PerformanceCards, KnowledgeBaseCards, TeamSummary, RecentFlowPilotSessions. Every stat/card navigates to its detail page on click.
  • Sidebar sections: Dashboard → RESOLVE (Active Sessions, Escalations) → KNOWLEDGE (Flows, Step Library, Scripts, Review Queue) → INSIGHTS (Exports, Analytics, FlowPilot Analytics). Footer: User Guides, Feedback, Account, Collapse.

Common Tasks

  • New endpoint: Create in endpoints/ → add to router.py → schema in schemas/ → tests → frontend API client
  • New page: Create in pages/ → add route in router.tsx → nav link in AppLayout.tsx
  • New public route (no auth): Add at top level in router.tsx alongside /login, /register — NOT inside the ProtectedRoute/AppLayout children.
  • Schema change: Update model → alembic revision --autogenerate -m "desc" → review → alembic upgrade head
  • New frontend API module: Types in types/ → export from types/index.ts → client in api/ → export from api/index.ts

Coding Standards

Python

  • Type hints everywhere, async/await for DB, Pydantic for validation, DateTime(timezone=True) always

TypeScript

  • Interfaces for all data, const over let, functional components + hooks, reusable logic in custom hooks

Git

  • Format: type: description (feat, fix, refactor, docs, test, chore)
  • Always include Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
  • Always create feature branch BEFORE committing: git checkout -b feat/feature-name
  • Large features: commit per phase with npm run build validation

After Completing Work

When a feature, fix, or significant piece of work is finished and merged/committed:

  1. Update CURRENT-STATE.md — move completed items, update "In Progress" and "What's Next" sections
  2. Update 03-DEVELOPMENT-ROADMAP.md — check off completed work, update phase status
  3. Close related GitHub Issues — use gh issue close #N for any issues resolved by the work
  4. Update CLAUDE.md if the work introduced new patterns, lessons learned, or changed project structure

Deployment (Railway)

  • Production: resolutionflow.com (frontend), api.resolutionflow.com (backend)
  • Auto-deploys on push to main
  • PR environments auto-created (need manual domain generation in Railway dashboard)
  • PR envs need VITE_API_URL set with https:// prefix on frontend service
  • ALLOW_RAILWAY_ORIGINS=true enables CORS for *.up.railway.app
  • Shared Variables (project-level in Railway dashboard) auto-propagate to all environments including PR envs — use for secrets like ANTHROPIC_API_KEY
  • Super admin utility: backend/make_superadmin_simple.py list|<email>

gstack

Use /browse from gstack for all web browsing — never use mcp__claude-in-chrome__* tools.

Available skills: /office-hours, /plan-ceo-review, /plan-eng-review, /plan-design-review, /design-consultation, /review, /ship, /browse, /qa, /qa-only, /design-review, /setup-browser-cookies, /retro, /investigate, /document-release, /codex, /careful, /freeze, /guard, /unfreeze, /gstack-upgrade


Future Roadmap

  • Phase 3: PSA integrations (ConnectWise in progress), file attachments, client context, analytics
  • Phase 4: Additional PSA integrations (Autotask/Kaseya), PowerShell automation, enterprise SSO

Quick Reference

What Where
API Docs http://localhost:8000/api/docs
Detailed Status CURRENT-STATE.md
Development Roadmap 03-DEVELOPMENT-ROADMAP.md
GitHub Issues gh issue list --state open
Bugs & Fixes CLAUDE.md → Critical Lessons Learned section
Feature Specs 04-FEATURE-SPECIFICATIONS.md
Design System docs/plans/Frontend/DESIGN_SYSTEM_GUIDE.md
Dev Environment DEV-ENV.md — devserver01 setup, Docker, CORS, networking