Add CW security roles reference docs and PSA ticket management plan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
406 lines
22 KiB
Markdown
406 lines
22 KiB
Markdown
# CLAUDE.md - Patherly / ResolutionFlow Project Context
|
|
|
|
> **Last Updated:** April 16, 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 | `patherly` (internal name) |
|
|
| Docker containers | `resolutionflow_postgres`, `resolutionflow_frontend`, `resolutionflow_backend` |
|
|
| Backend, frontend UI, production URLs | **ResolutionFlow** |
|
|
|
|
- **Brand assets:** `brand-assets/` (source SVGs), `frontend/src/assets/brand/` (app assets), `frontend/public/icons/` (favicon)
|
|
- **Logo:** 30px gradient square (ember orange) + "ResolutionFlow" in Bricolage Grotesque 700
|
|
- **Layout:** Icon rail sidebar (72px default) with hover flyout panels. Pinnable to full 260px sidebar.
|
|
- **Terminology:** User-facing label is "Flows" (not "Trees"). Procedural flows are called "Projects" in the UI. Step Library is called "Solutions Library" in the UI. `tree_type` column values unchanged in DB.
|
|
- **Reference mockups:** `docs/mockups/` (HTML files, open in browser)
|
|
|
|
## 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 (55+ API endpoints, 100+ integration tests)
|
|
- **Frontend:** Core features complete, Tree Editor functional
|
|
- **Database:** PostgreSQL with Docker, 101 migrations
|
|
- **Detailed status:** [CURRENT-STATE.md](CURRENT-STATE.md)
|
|
|
|
### What's In Progress
|
|
|
|
- GTM validation: Shadow & Ship — founder dogfooding for 2 weeks, then 5 colleague pilot
|
|
- Solutions Library spec written (`docs/plans/2026-03-23-solutions-library-design.md`), implementation post-pilot
|
|
- Remaining open issues: #66 Templates + Import/Export, #60 Recurring Issue Detection, #58 Step Feedback Flag
|
|
|
|
---
|
|
|
|
## Tech Stack
|
|
|
|
### Backend
|
|
Python FastAPI, PostgreSQL 16 (async SQLAlchemy 2.0 + asyncpg), Alembic, JWT (python-jose) + bcrypt, Pydantic v2, APScheduler 3.x
|
|
|
|
### Frontend
|
|
React 19 + Vite + TypeScript, Tailwind CSS v4 (CSS-only config in `index.css`), Zustand (immer + zundo), React Router v7, Axios, Lucide React
|
|
|
|
---
|
|
|
|
## Key Project Structure
|
|
|
|
```
|
|
patherly/
|
|
├── backend/app/
|
|
│ ├── main.py # FastAPI entry point
|
|
│ ├── api/endpoints/ # Route handlers
|
|
│ ├── api/deps.py # Auth dependencies
|
|
│ ├── core/ # config, database, permissions, security, audit, rate_limit
|
|
│ ├── models/ # SQLAlchemy models
|
|
│ ├── schemas/ # Pydantic schemas
|
|
│ └── services/psa/ # PSA provider abstraction (connectwise/, autotask/, halopsa/)
|
|
├── backend/alembic/ # Migrations (001-070 sequential, then hash IDs)
|
|
├── backend/tests/ # pytest integration tests
|
|
├── frontend/src/
|
|
│ ├── api/ # Axios client + endpoint modules
|
|
│ ├── components/ # UI components
|
|
│ ├── hooks/ # usePermissions, useSessionTimer, etc.
|
|
│ ├── pages/ # Page components
|
|
│ ├── store/ # Zustand stores
|
|
│ └── types/ # TypeScript interfaces
|
|
└── 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=<openssl rand -hex 32>
|
|
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
|
|
|
|
All reference materials in `docs/connectwise/`. See [CONNECTWISE-API-REFERENCE.md](docs/connectwise/CONNECTWISE-API-REFERENCE.md) first.
|
|
|
|
### Best Practices Documentation
|
|
|
|
Read `docs/connectwise/best-practices/` BEFORE implementing any CW API integration code:
|
|
|
|
- `PSA-API-Requests.md` — HTTP methods, condition syntax, PATCH format. READ FIRST.
|
|
- `PSA-Callbacks.md` — Callback matrix, HMAC verification.
|
|
- `PSA-Pagination.md` — Forward-Only vs Navigable, Link headers.
|
|
- `PSA-Service-Tickets.md` — Ticket field mappings.
|
|
- `PSA-Versioning.md` — Pin `application/vnd.connectwise.com+json; version=2025.16`.
|
|
- `PSA-Cloud-URL-Formatting.md` — Dynamic base URL via `/login/companyinfo/{companyId}`.
|
|
- `Bundled-Requests.md` — Batch via `/system/bundles`.
|
|
- `PSA-Markdown.md` — Notes support markdown.
|
|
- `PSA-Company-Synchronization.md` — Filter companies by Status/Type.
|
|
- `PSA-Data-Protection.md` — Request minimal permissions (MY not ALL).
|
|
|
|
### Reference Files (read in this order)
|
|
|
|
1. `docs/connectwise/CONNECTWISE-API-REFERENCE.md` — Auth patterns, endpoint map, field mappings.
|
|
2. `docs/connectwise/connectwise-psa-resolutionflow-reference.json` — Extracted OpenAPI 3.0.1 spec (670 endpoints, 342 schemas).
|
|
3. `docs/connectwise/connectwise-psa-openapi-full.json` — Full spec (1838 endpoints). Only if you need something outside the subset.
|
|
|
|
### 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 ResolutionFlow app, NOT per-tenant. Per-connection: `company_id`, `public_key`, `private_key`, `server_url`
|
|
- All PSA code in `services/psa/` — `PSAProvider` abstract base, `ConnectWiseProvider` impl, `PsaProviderRegistry` for multi-PSA dispatch
|
|
- PSA endpoints in `api/endpoints/integrations.py` — connection CRUD, ticket ops, member mapping
|
|
- Credentials encrypted via `services/psa/encryption.py` (Fernet); stored per-team, never per-user
|
|
- In-memory TTL cache in `services/psa/cache.py` for board/status/priority lookups
|
|
- Integration flows: Session → Ticket Notes via `POST /service/tickets/{id}/notes`; Ticket Context → FlowPilot via ticket details/company/configs; Callbacks via `/system/callbacks`
|
|
|
|
---
|
|
|
|
## Development Commands
|
|
|
|
```bash
|
|
# PostgreSQL (run from VPS SSH — docker not available in code-server, see Lesson 103)
|
|
docker start resolutionflow_postgres
|
|
|
|
# Backend (from backend/)
|
|
source venv/bin/activate
|
|
uvicorn app.main:app --reload
|
|
|
|
# Frontend (from frontend/) — requires Node 20 (use nvm: nvm use 20)
|
|
npm run dev
|
|
|
|
# Tests (from backend/)
|
|
pytest --override-ini="addopts="
|
|
|
|
# TypeScript check (use in code-server — avoids EACCES on dist/, see Lesson 105)
|
|
npx tsc -b
|
|
|
|
# Frontend build — stricter than tsc, always use as final check before push
|
|
cd frontend && npm run build
|
|
|
|
# Migrations
|
|
cd backend && alembic upgrade head
|
|
alembic revision --autogenerate -m "Description" # do NOT pass --rev-id; Alembic generates hash IDs
|
|
|
|
# Access PostgreSQL (VPS SSH)
|
|
docker exec -it resolutionflow_postgres psql -U postgres -d resolutionflow
|
|
|
|
# CI runs on Gitea (NOT GitHub Actions): https://gitea.resolutionflow.com/chihlasm/resolutionflow/actions
|
|
```
|
|
|
|
### URLs & Test Users
|
|
|
|
- Frontend: `http://localhost:5173` | Backend: `http://localhost:8000` | API Docs: `http://localhost:8000/api/docs`
|
|
- Test password: `TestPass123!` — users: `admin@`, `teamadmin@`, `engineer@`, `pro@` (all `@resolutionflow.example.com`)
|
|
|
|
---
|
|
|
|
## Critical Lessons Learned
|
|
|
|
> Lessons 1-70 archived to `docs/LESSONS-ARCHIVE.md` — fixes are baked into the codebase.
|
|
|
|
**71. Enhancement/branch_addition proposals cannot be directly approved:** Backend returns 400 — requires `modified_flow_data` via "Edit & Publish". Only `new_flow` proposals support direct approve.
|
|
|
|
**72. `ai_sessions.status` column is `VARCHAR(30)`:** Must fit `requesting_escalation` (23 chars). Verify length when adding new status values.
|
|
|
|
**73. `get_db` rolls back on exception:** Prevents `InFailedSQLTransaction` cascade. Never remove the `await session.rollback()` in the dependency.
|
|
|
|
**74. FlowPilot action bar height chain:** `ViewTransitionOutlet` wrapper needs `flex flex-col`. If action bar disappears, walk `getBoundingClientRect()` from `app-shell` down.
|
|
|
|
**75. Dashboard prefill auto-submits:** `StartSessionInput` passes `{ state: { prefill } }`. Both `FlowPilotSessionPage` and `AssistantChatPage` auto-submit via `useEffect` + `prefillHandledRef` guard.
|
|
|
|
**76. Active session navigation guard:** `FlowPilotSessionPage` uses `useBlocker` to intercept navigation. "Pause & Leave" auto-pauses before proceeding.
|
|
|
|
**77. Prefer manual Alembic migrations for targeted changes:** `--autogenerate` picks up all table drift. 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":** Appears on login, register, and `<title>`. Not "Decision Tree Platform".
|
|
|
|
**79. Custom modals must be mobile-responsive:** Use `items-end sm:items-center` + `max-w-full sm:max-w-lg`. See `Modal.tsx` and `PrepareSessionModal.tsx`.
|
|
|
|
**80. TopBar search collapses to icon on mobile:** Full bar (`hidden sm:block`) + icon fallback (`sm:hidden`). Both open `CommandPalette`.
|
|
|
|
**81. Never use `transition: all` in landing.css:** Specify exact properties. `transition: all` animates layout and causes jank.
|
|
|
|
**82. `bun` requires PATH setup:** `export BUN_INSTALL="$HOME/.bun" && export PATH="$BUN_INSTALL/bin:$PATH"`. Chromium deps: `libatk1.0-0 libatk-bridge2.0-0 libcups2 libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2`.
|
|
|
|
**84. AI session `abandoned` status is fully wired:** `POST /ai-sessions/{id}/abandon` with optional `reason`. Frontend: `aiSessionsApi.abandonSession()` → `useFlowPilotSession().abandonSession()`.
|
|
|
|
**85. Date range filter end dates must use end-of-day:** Set `toDate.setHours(23, 59, 59, 999)`. For string inputs append `T23:59:59.999Z`. See `SessionHistoryPage.tsx`.
|
|
|
|
**86. Script Builder:** `/script-builder` — `ScriptBuilderSession` model, `script_builder_service.py`, endpoints at `/scripts/builder/`. FlowPilot handoff via `action_type: "open_script_builder"` + sessionStorage context.
|
|
|
|
**87. FlowPilot must ask GUI vs script preference:** Ask BEFORE suggesting either approach. See `FLOWPILOT_SYSTEM_PROMPT` in `flowpilot_engine.py`.
|
|
|
|
**88. Charcoal palette:** Sidebar `#0e1016`, page `#16181f`, cards `#1e2028`, borders `#2a2e3a`. All via CSS variables in `index.css` `@theme`. Accent is electric blue (#60a5fa).
|
|
|
|
**92. `tsc -b` in Dockerfile enforces `noUnusedLocals`/`noUnusedParameters` as hard errors.** After refactors, trace every import and destructured prop. Check IDE yellow squiggles before pushing.
|
|
|
|
**93. FlowPilot actions live in the page header, not a bottom bar:** Resolve/Escalate/Share Update in header. Desktop: inline + `⋯` overflow (Pause/Close). Mobile: single `⋯`. Bottom = message input only.
|
|
|
|
**94. Frontend chat uses `unified_chat_service`, not `assistant_chat_service`:** `AssistantChatPage` → `/ai-sessions/{id}/chat` → `unified_chat_service.py`. Never wire chat into `assistant_chat.py`.
|
|
|
|
**95. Image upload → AI vision:** `uploadsApi.upload()` → `upload_ids` in message → backend fetches S3 → `storage_service.resize_image_for_vision()` (Pillow, 1568px, PNG→JPEG) → base64 → Claude multimodal. Max 3 images/message. Images NOT stored in history.
|
|
|
|
**96. `bg-accent` is electric blue — never use for code/kbd.** Use `bg-code` for code blocks, `bg-white/[0.12]` for inline code/badges, `bg-white/[0.08]` for kbd.
|
|
|
|
**97. Railway S3 provisioned:** Bucket `resolutionflow-uploads`. Variables: `STORAGE_ENDPOINT`, `STORAGE_ACCESS_KEY`, `STORAGE_SECRET_KEY`, `STORAGE_BUCKET_NAME`, `STORAGE_REGION`. boto3 in `storage_service.py`.
|
|
|
|
**98. `lazyWithRetry` for lazy routes:** Use instead of `React.lazy` — auto-reloads on chunk failures with 10s sessionStorage debounce.
|
|
|
|
**99. `text-secondary` renders invisible on dark backgrounds:** Maps to `--color-secondary` (dark surface). Use `text-muted-foreground` (`#848b9b`) for readable secondary text. Never use `text-muted` for body text.
|
|
|
|
**100. Hover pop-out card pattern:** `pointer-events-none` on scrim (`z-40`), `z-50` expanded card with own `onClick`, dismiss via `onMouseLeave`. Never put handlers on scrim.
|
|
|
|
**101. AI marker format compliance:** `[QUESTIONS]`, `[ACTIONS]`, `[FORK]` parsed by `unified_chat_service.py`. History stores `display_content` (stripped). Each user message gets `[SYSTEM: ...]` reminder appended in `_call_anthropic_cached()`.
|
|
|
|
**102. TaskLane activation must happen in ALL chat response paths:** Three paths in `AssistantChatPage.tsx` — `handleSend`, `sendPrefill`, `handleResumeNew`. All must check `response.actions`/`response.questions` and call `setShowTaskLane(true)`.
|
|
|
|
**103. Docker not available in code-server:** Use VPS SSH: `docker exec resolutionflow_postgres psql -U postgres -d resolutionflow -t -c "SQL"`. Python also not available in container.
|
|
|
|
**104. `landing.css` uses `--lp-*` variables:** Never use `var(--color-*)` tokens in `landing.css`. Extend the `--lp-*` palette for new landing page colors.
|
|
|
|
**105. `npm run build` fails with `EACCES` on `dist/` in code-server:** Use `npx tsc -b` to verify TypeScript without writing to `dist/`.
|
|
|
|
**106. Guard async "select item → load data → apply state" flows:** Use `currentSelectionRef = useRef(id)` — update on every switch, bail after each `await` if ref no longer matches. See `AssistantChatPage.tsx` `currentChatRef`.
|
|
|
|
**107. Startup routines use `_admin_session_factory()`:** RLS is enabled; `get_db()` at startup has no `app.current_account_id`, so queries return 0 rows. Affects lifespan, `ensure_service_account`, seed scripts.
|
|
|
|
**108. Tables with no `account_id` (never add to RLS migrations):** `script_categories`, `platform_steps`, `template_trees`, `plan_feature_defaults`, `accounts`. Scan at class level, not file level — one `.py` file can have multiple classes with different columns.
|
|
|
|
**109. `tree_shares.account_id` must equal `tree.account_id`:** Use tree owner's tenant, not the actor's. Cross-tenant admin shares become invisible after RLS enforcement.
|
|
|
|
**110. Backfill `account_id` migrations require service-code audit:** Grep all `ModelClass(` sites, verify `account_id=` is passed. SQLAlchemy accepts `None` silently; RLS WITH CHECK surfaces it at runtime as `InsufficientPrivilegeError`.
|
|
|
|
**111. Global Axios interceptor fires before component `.catch()`:** Fix optional-data endpoints at the source — return `[]`/`{}` on provider failure instead of raising 502. See `list_boards` in `integrations.py`.
|
|
|
|
## 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`, `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
|
|
|
|
**Source of truth:** [DESIGN-SYSTEM.md](DESIGN-SYSTEM.md) — always read before visual/UI decisions.
|
|
|
|
- **Theme:** Flat, high-contrast dark (Sentry/PostHog-inspired). No glass morphism, no backdrop blur, no gradients on surfaces. Fonts: IBM Plex Sans (body), Bricolage Grotesque (headings), JetBrains Mono (code).
|
|
- **Backgrounds:** `bg-page` (`#16181f`), `bg-sidebar` (`#0e1016`), `bg-card` (`#1e2028`), `bg-elevated` (`#2a2d38`)
|
|
- **Cards:** `bg-card` + 1px `border-default` (`#2a2e3a`), 8px radius. Hover: `border-hover` (`#3d4252`)
|
|
- **Buttons:** Primary: solid `accent` (#60a5fa / #2563eb), white text, 5px radius. Ghost: transparent + 1px border.
|
|
- **Inputs:** `bg-input` (`#252830`) + 1px `border-default`, 5px radius. Focus: `border-color: accent` + `box-shadow: 0 0 0 2px accent-dim`
|
|
- **Text:** `text-heading` → `text-primary` → `text-muted-foreground` (`#848b9b`). **NEVER `text-secondary`** — maps to a dark surface color.
|
|
- **Functional colors:** `#34d399` success, `#fbbf24` warning, `#f87171` danger, `#67e8f9` info — each has `-dim` at 10% opacity
|
|
- **Deprecated:** No `glass-card`, `backdrop-filter: blur()`, ambient orbs, ember orange (`#f97316`), or cyan as accent
|
|
|
|
---
|
|
|
|
## 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'`
|
|
- **Custom step flow:** `CustomStepModal` → `PostStepActionModal` → `ContinuationModal`. Use `findCustomStep()` not `findNode()` for custom step UUIDs.
|
|
- **Session sharing:** `ShareSessionModal` + `SharedSessionPage`. Utils in `lib/sessionShare.ts`. Share URLs: `/shared/sessions/:token`.
|
|
- **Routing helper:** Use `getTreeNavigatePath()` and `getTreeEditorPath()` from `@/lib/routing` for all tree/session navigation.
|
|
- **Account section:** `AccountLayout` has NO sidebar nav. New account pages: route under `account` children in `router.tsx` + link card in `AccountSettingsPage`.
|
|
- **Dashboard cockpit:** `QuickStartPage` — `StartSessionInput` + `PendingEscalations`, `ActiveFlowPilotSessions`, `RecentFlowPilotSessions`. Collapsible section for `PerformanceCards`, `KnowledgeBaseCards`, `TeamSummary`.
|
|
- **Sidebar:** Amber "New Session" → Home → RESOLVE → KNOWLEDGE (Flows, Scripts) → INSIGHTS. Footer: Account, Pin/Unpin.
|
|
|
|
---
|
|
|
|
## Common Tasks
|
|
|
|
- **New endpoint:** Create in `endpoints/` → add to `router.py` → schema in `schemas/` → tests → frontend API client
|
|
- **New page:** Create in `pages/` → route in `router.tsx` → nav link in `AppLayout.tsx`
|
|
- **New public route:** Add at top level in `router.tsx` (alongside `/login`) — NOT inside `ProtectedRoute`/`AppLayout`
|
|
- **Schema change:** Update model → `alembic revision -m "desc"` (no `--rev-id`) → 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 validation, `DateTime(timezone=True)` always.
|
|
|
|
### TypeScript
|
|
Interfaces for all data, `const` over `let`, functional components + hooks.
|
|
|
|
### Git
|
|
- Format: `type: description` (feat, fix, refactor, docs, test, chore)
|
|
- Always include `Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>`
|
|
- Create feature branch BEFORE committing: `git checkout -b feat/feature-name`
|
|
- **Remote is Gitea:** Push to `gitea.resolutionflow.com/chihlasm/resolutionflow`. Mirrors to GitHub via `.gitea/workflows/mirror-to-github.yml` — never push directly to GitHub.
|
|
|
|
### After Completing Work
|
|
1. Update `CURRENT-STATE.md`
|
|
2. Update `03-DEVELOPMENT-ROADMAP.md`
|
|
3. Close related GitHub Issues: `gh issue close #N`
|
|
4. Update `CLAUDE.md` if new patterns or lessons emerged
|
|
|
|
---
|
|
|
|
## gstack (Browser & Workflow Skills)
|
|
|
|
**Web browsing:** Always use `/browse`. Never use `mcp__claude-in-chrome__*` tools.
|
|
|
|
**Skills:** `/office-hours` · `/plan-ceo-review` · `/plan-eng-review` · `/plan-design-review` · `/design-consultation` · `/review` (PR review) · `/ship` · `/browse` (headless QA) · `/qa` (QA + fix) · `/qa-only` · `/design-review` (visual QA) · `/setup-browser-cookies` · `/retro` · `/investigate` · `/document-release` · `/codex` · `/careful` · `/freeze` · `/unfreeze` · `/guard` · `/gstack-upgrade`
|
|
|
|
---
|
|
|
|
## Deployment (Railway)
|
|
|
|
- **Production:** `resolutionflow.com` (frontend), `api.resolutionflow.com` (backend)
|
|
- Deploy pipeline: push to Gitea → mirrors to GitHub → Railway watches `main`
|
|
- PR envs: need manual domain generation + `VITE_API_URL` with `https://` prefix
|
|
- `ALLOW_RAILWAY_ORIGINS=true` enables CORS for `*.up.railway.app`
|
|
- Shared Variables auto-propagate to all PR envs — use for `ANTHROPIC_API_KEY` etc.
|
|
- Super admin: `backend/make_superadmin_simple.py list|<email>`
|
|
|
|
---
|
|
|
|
## 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` |
|
|
| Design System | [DESIGN-SYSTEM.md](DESIGN-SYSTEM.md) |
|
|
| Dev Environment | [DEV-ENV.md](DEV-ENV.md) — VPS setup, Docker, CORS, networking |
|
|
|
|
|
|
<!-- gitnexus:start -->
|
|
# GitNexus — Code Intelligence
|
|
|
|
This project is indexed by GitNexus as **resolutionflow**. Use it selectively — for routine additive work (new endpoints, new components, isolated fixes) just read the files directly. GitNexus earns its cost when you're about to touch something genuinely central with many callers.
|
|
|
|
> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.
|
|
|
|
## When to Use It
|
|
|
|
**Use GitNexus when:**
|
|
- Touching a core shared symbol with many callers — `flowpilot_engine`, `unified_chat_service`, auth middleware, `get_db`, shared hooks
|
|
- Renaming anything used across multiple files
|
|
- Tracing an unfamiliar bug through a call chain you haven't read
|
|
- Assessing whether a refactor is safe before starting
|
|
|
|
**Skip GitNexus when:**
|
|
- Adding a new endpoint, component, or isolated feature
|
|
- Fixing a bug in a self-contained file
|
|
- Making changes you can already see the full scope of by reading the file
|
|
|
|
## Useful Tools
|
|
|
|
| Tool | When to use | Command |
|
|
|------|-------------|---------|
|
|
| `query` | Find code by concept when you don't know where to look | `gitnexus_query({query: "auth validation"})` |
|
|
| `context` | See all callers/callees of a symbol before touching it | `gitnexus_context({name: "symbolName"})` |
|
|
| `impact` | Blast radius check before editing a shared symbol | `gitnexus_impact({target: "X", direction: "upstream"})` |
|
|
| `rename` | Safe multi-file rename | `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` |
|
|
|
|
## Keeping the Index Fresh
|
|
|
|
A PostToolUse hook re-indexes automatically after `git commit`. To manually refresh:
|
|
|
|
```bash
|
|
npx gitnexus analyze
|
|
```
|
|
|
|
<!-- gitnexus:end -->
|