docs: audit and improve CLAUDE.md — add Phase C/D, trim verbose sections

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-06 00:40:34 -05:00
parent 1e57aa8323
commit cf6d8bd57b

186
CLAUDE.md
View File

@@ -48,7 +48,7 @@ When adding new frontend pages or components, use "ResolutionFlow" for any user-
## Current State ## Current State
- **Phase:** Phase 2.5 - Step Library Foundation (In Progress) - **Phase:** Phase 2.5 - Step Library Foundation (In Progress)
- **Backend:** Complete (25+ API endpoints, 50+ integration tests, all passing) - **Backend:** Complete (25+ API endpoints, 60+ integration tests, all passing)
- **Frontend:** Core features complete, Tree Editor functional, Settings page added - **Frontend:** Core features complete, Tree Editor functional, Settings page added
- **Database:** PostgreSQL with Docker (container name: `patherly_postgres`) - **Database:** PostgreSQL with Docker (container name: `patherly_postgres`)
@@ -125,6 +125,19 @@ When adding new frontend pages or components, use "ResolutionFlow" for any user-
- B7: Refresh token rotation — JTI-based revocation, meaningful logout (migration 013) - B7: Refresh token rotation — JTI-based revocation, meaningful logout (migration 013)
- Access token TTL reduced from 15 to 5 minutes - Access token TTL reduced from 15 to 5 minutes
- All endpoints now use `get_current_active_user` (not `get_current_user`) - All endpoints now use `get_current_active_user` (not `get_current_user`)
- **Permissions UX (Phase C):**
- Super admin bypass in tree list filter (`build_tree_access_filter` returns `sa_true()`)
- Audit log table (`audit_logs`) with JSONB details, integrated at admin + tree delete endpoints
- Soft delete for trees (`deleted_at` + `deleted_by` columns, migration 015)
- ProtectedRoute supports optional `requiredRole` prop for role-based route guards
- TreeEditorPage checks `canEditTree()` after fetch, before loading into editor
- Reusable `ConfirmDialog` component + tree delete UI on library page
- CustomStepModal hides "Type My Own" tab for users without `canCreateSteps`
- **Permissions Cleanup (Phase D):**
- Password complexity validation: requires uppercase, lowercase, and digit (min 10 chars)
- Soft delete cascade: cleans up folder/tag junction entries on tree delete
- Debug endpoint `/debug/cors` gated behind `if settings.DEBUG:`
- Tag search escapes SQL wildcards (`%`, `_`) before LIKE query
- **Session Scratchpad (Floating Overlay):** - **Session Scratchpad (Floating Overlay):**
- Fixed-position overlay panel (420px wide, 55vh tall) on right edge - Fixed-position overlay panel (420px wide, 55vh tall) on right edge
- Floating button when collapsed, slide-in panel when expanded - Floating button when collapsed, slide-in panel when expanded
@@ -182,12 +195,18 @@ patherly/
│ │ │ │ ├── admin.py # Admin user management (6 endpoints) │ │ │ │ ├── admin.py # Admin user management (6 endpoints)
│ │ │ │ ├── trees.py # Trees CRUD + search │ │ │ │ ├── trees.py # Trees CRUD + search
│ │ │ │ ├── sessions.py # Sessions + export │ │ │ │ ├── sessions.py # Sessions + export
│ │ │ │ ── invite.py # Invite code management │ │ │ │ ── invite.py # Invite code management
│ │ │ │ ├── categories.py # Tree categories (global + team)
│ │ │ │ ├── tags.py # Tree tags + autocomplete
│ │ │ │ ├── folders.py # User folders (hierarchy)
│ │ │ │ ├── steps.py # Step library CRUD + search
│ │ │ │ └── step_categories.py # Step categories
│ │ │ ├── deps.py # Auth dependencies │ │ │ ├── deps.py # Auth dependencies
│ │ │ └── router.py │ │ │ └── router.py
│ │ ├── core/ │ │ ├── core/
│ │ │ ├── config.py # Settings (pydantic-settings) │ │ │ ├── config.py # Settings (pydantic-settings)
│ │ │ ├── database.py # Async SQLAlchemy │ │ │ ├── database.py # Async SQLAlchemy
│ │ │ ├── audit.py # Centralized audit log helper (log_audit)
│ │ │ ├── permissions.py # Centralized RBAC (role checks, content guards) │ │ │ ├── permissions.py # Centralized RBAC (role checks, content guards)
│ │ │ ├── rate_limit.py # Shared slowapi limiter (disabled in DEBUG) │ │ │ ├── rate_limit.py # Shared slowapi limiter (disabled in DEBUG)
│ │ │ ├── security.py # JWT + password hashing + token rotation │ │ │ ├── security.py # JWT + password hashing + token rotation
@@ -205,7 +224,8 @@ patherly/
│ │ │ ├── folder.py # UserFolder model │ │ │ ├── folder.py # UserFolder model
│ │ │ ├── step_category.py # StepCategory model │ │ │ ├── step_category.py # StepCategory model
│ │ │ ├── step_library.py # StepLibrary, StepRating, StepUsageLog │ │ │ ├── step_library.py # StepLibrary, StepRating, StepUsageLog
│ │ │ ── refresh_token.py # RefreshToken model (JTI-based revocation) │ │ │ ── refresh_token.py # RefreshToken model (JTI-based revocation)
│ │ │ └── audit_log.py # AuditLog model (JSONB details, indexed)
│ │ └── schemas/ # Pydantic schemas │ │ └── schemas/ # Pydantic schemas
│ ├── alembic/ # Database migrations │ ├── alembic/ # Database migrations
│ ├── scripts/ │ ├── scripts/
@@ -238,11 +258,12 @@ patherly/
│ │ │ ├── treeEditorStore.ts # Tree editor state (immer + zundo) │ │ │ ├── treeEditorStore.ts # Tree editor state (immer + zundo)
│ │ │ └── userPreferencesStore.ts # User preferences (NEW) │ │ │ └── userPreferencesStore.ts # User preferences (NEW)
│ │ ├── components/ │ │ ├── components/
│ │ │ ├── common/ # Modal, ErrorBoundary, ThemeToggle │ │ │ ├── common/ # Modal, ErrorBoundary, ThemeToggle, ConfirmDialog
│ │ │ ├── layout/ # AppLayout, ProtectedRoute │ │ │ ├── layout/ # AppLayout, ProtectedRoute
│ │ │ ├── tree-editor/ # Tree editor components │ │ │ ├── tree-editor/ # Tree editor components
│ │ │ ├── tree-preview/ # Visual tree preview │ │ │ ├── tree-preview/ # Visual tree preview
│ │ │ ├── step-library/ # Step library browser, forms, modals │ │ │ ├── step-library/ # Step library browser, forms, modals
│ │ │ ├── library/ # Tree library UI components
│ │ │ ├── session/ # Session modals, scratchpad floating overlay │ │ │ ├── session/ # Session modals, scratchpad floating overlay
│ │ │ └── ui/ # MarkdownContent │ │ │ └── ui/ # MarkdownContent
│ │ ├── pages/ │ │ ├── pages/
@@ -492,6 +513,16 @@ await db.execute(
``` ```
Accessing relationships on newly created objects triggers lazy loading, which fails in async SQLAlchemy. Use direct SQL inserts for junction tables instead. Accessing relationships on newly created objects triggers lazy loading, which fails in async SQLAlchemy. Use direct SQL inserts for junction tables instead.
### SQLAlchemy: Multiple FKs to Same Table Require `foreign_keys`
When a model has two FKs to the same table (e.g., Tree has `author_id` and `deleted_by` both pointing to `users`), specify `foreign_keys` on BOTH sides:
```python
# On Tree model
author = relationship("User", foreign_keys=[author_id], back_populates="trees")
# On User model
trees = relationship("Tree", foreign_keys="[Tree.author_id]", back_populates="author")
```
### React Router: Clear Dirty State Before Navigation ### React Router: Clear Dirty State Before Navigation
```tsx ```tsx
@@ -626,49 +657,10 @@ For detailed parameters, request/response schemas, and examples, visit the API d
## Data Models ## Data Models
### Tree Structure (JSONB) Key JSONB structures stored in PostgreSQL. See `frontend/src/types/` for full TypeScript interfaces.
```typescript - **Tree Structure:** Recursive node tree (`decision`/`action`/`solution` types with `children[]`). See `types/tree.ts`.
interface TreeStructure { - **Session Decisions:** Array of `{node_id, question, answer, notes, timestamp}`. Timestamps are ISO strings, not datetime objects.
id: string
type: 'decision' | 'action' | 'solution'
// Decision nodes
question?: string
help_text?: string
options?: Array<{
id: string
label: string
next_node_id?: string
}>
// Action nodes
title?: string
description?: string
commands?: string[]
next_node_id?: string
// Solution nodes
title?: string
description?: string
steps?: string[]
// All nodes can have children
children?: TreeStructure[]
}
```
### Session Decisions (JSONB)
```typescript
interface Decision {
node_id: string
question?: string
answer: string
notes?: string
timestamp: string // ISO string, not datetime object
}
```
--- ---
@@ -728,34 +720,10 @@ Position overlay at `right-2` (not `right-0`) so it sits inside the page scrollb
## Common Tasks ## Common Tasks
### Adding a New API Endpoint - **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`
1. Create route in `backend/app/api/endpoints/` - **Schema change:** Update model → `alembic revision --autogenerate -m "desc"` → review → `alembic upgrade head`
2. Add to router in `backend/app/api/router.py` - **New frontend API module:** Types in `types/` → export from `types/index.ts` → client in `api/` → export from `api/index.ts`
3. Create/update Pydantic schemas in `backend/app/schemas/`
4. Add tests in `backend/tests/`
5. Update API client in `frontend/src/api/`
### Adding a New API Client Module (Frontend)
1. Create types in `frontend/src/types/modulename.ts`
2. Export types from `frontend/src/types/index.ts`
3. Create API client in `frontend/src/api/modulename.ts` following existing pattern
4. Export from `frontend/src/api/index.ts`
5. Import in components: `import { moduleApi } from '@/api'`
### Adding a New Page
1. Create page component in `frontend/src/pages/`
2. Add route in `frontend/src/router.tsx`
3. Add navigation link in `AppLayout.tsx` if needed
### Modifying Database Schema
1. Update model in `backend/app/models/`
2. Create migration: `alembic revision --autogenerate -m "description"`
3. Review generated migration file
4. Apply: `alembic upgrade head`
--- ---
@@ -798,28 +766,11 @@ Position overlay at `right-2` (not `right-0`) so it sits inside the page scrollb
### Phase 2.5 (In Progress) ### Phase 2.5 (In Progress)
- ✅ Step Categories database and API - Custom step continuation flow refinements
- ✅ Step Library database schema (step_library, step_ratings, step_usage_log) - Tree forking from sessions with custom steps
- ✅ Step Library CRUD API with search and ratings
- ✅ User Preferences (Settings page, export format default)
- 🔲 Step Library browser component (frontend)
- 🔲 Add Custom Step button in tree navigation
- 🔲 Custom step creation modal
- 🔲 Personal tree branching (add custom steps during sessions)
- 🔲 Tree forking and sharing
### Phase 3 (Planned) ### Phase 3 — File attachments, offline mode, client context, analytics
### Phase 4 — PSA integrations (ConnectWise, Kaseya), PowerShell automation, enterprise SSO
- File attachments (screenshots, logs)
- Offline mode (Service Workers + IndexedDB)
- Client context system
- Analytics dashboard
### Phase 4 (Planned)
- API & integrations (ConnectWise, Kaseya)
- PowerShell automation execution
- Enterprise features (SSO, white-labeling)
--- ---
@@ -933,57 +884,20 @@ Railway creates isolated preview environments for each pull request.
- Migrations run automatically via `releaseCommand` - Migrations run automatically via `releaseCommand`
- Domains must be generated manually for each PR service - Domains must be generated manually for each PR service
**Debug Endpoints (available in PR environments):** **Debug Endpoints (only when `DEBUG=True`):**
- `/debug/cors` - Check CORS configuration (allow_railway_origins, cors_mode) - `/debug/cors` - Check CORS configuration (requires `DEBUG=True` in environment)
### Railway CLI (Local) ### Railway CLI (Local)
The Railway CLI can be installed locally for managing deployments, viewing logs, and checking service status. Railway CLI installed via npm in project root (gitignored). Services: `patherly` (backend), `hopeful-liberation` (frontend), `Postgres` (DB).
**Setup on a new machine:**
```powershell ```powershell
# 1. Install Railway CLI via npm (in project root) # Common commands (run from project root)
cd C:\Dev\Projects\patherly
npm init -y
npm install @railway/cli
# 2. Login to Railway
./node_modules/.bin/railway login
# 3. Link to the project
./node_modules/.bin/railway link
# Select: selfless-grace → production
```
**Common Commands:**
```powershell
# Check service status
./node_modules/.bin/railway service status --service patherly
./node_modules/.bin/railway service status --all ./node_modules/.bin/railway service status --all
# View logs
./node_modules/.bin/railway service logs --service patherly ./node_modules/.bin/railway service logs --service patherly
# Check environment variables
./node_modules/.bin/railway variables --service patherly ./node_modules/.bin/railway variables --service patherly
# Deploy new code (from backend directory)
cd backend && ../node_modules/.bin/railway up --service patherly
# Redeploy existing build
./node_modules/.bin/railway service redeploy --service patherly --yes
``` ```
**Services:**
- `patherly` - Backend API
- `hopeful-liberation` - Frontend
- `Postgres` - Database
**Note:** The `node_modules/`, `package.json`, and `package-lock.json` files for the Railway CLI are gitignored (local tooling only).
--- ---
## Contact ## Contact