# 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](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](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](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](docs/archive/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](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](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`) ```bash 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= ACCESS_TOKEN_EXPIRE_MINUTES=5 REFRESH_TOKEN_EXPIRE_DAYS=7 REQUIRE_INVITE_CODE=true ``` ### Frontend (`frontend/.env.local` - optional) ```bash 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 ```powershell # 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 --log-failed # Failed job logs gh run watch --exit-status # Watch run until complete gh run view --json jobs --jq '.jobs[] | {name: .name, conclusion: .conclusion}' ``` ### URLs - Frontend: - Backend API: - API Docs: ### 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:** `title` → `question` → `description` → `content` → `label`. 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](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 ``. 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:** `CustomStepModal` → `PostStepActionModal` → `ContinuationModal` → 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](CURRENT-STATE.md) | | Development Roadmap | [03-DEVELOPMENT-ROADMAP.md](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](04-FEATURE-SPECIFICATIONS.md) | | Design System | [docs/plans/Frontend/DESIGN_SYSTEM_GUIDE.md](docs/plans/Frontend/DESIGN_SYSTEM_GUIDE.md) | | Dev Environment | [DEV-ENV.md](DEV-ENV.md) — devserver01 setup, Docker, CORS, networking |