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
- **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
- **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)
- Access token TTL reduced from 15 to 5 minutes
- 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):**
- Fixed-position overlay panel (420px wide, 55vh tall) on right edge
- Floating button when collapsed, slide-in panel when expanded
@@ -182,12 +195,18 @@ patherly/
│ │ │ │ ├── admin.py # Admin user management (6 endpoints)
│ │ │ │ ├── trees.py # Trees CRUD + search
│ │ │ │ ├── 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
│ │ │ └── router.py
│ │ ├── core/
│ │ │ ├── config.py # Settings (pydantic-settings)
│ │ │ ├── database.py # Async SQLAlchemy
│ │ │ ├── audit.py # Centralized audit log helper (log_audit)
│ │ │ ├── permissions.py # Centralized RBAC (role checks, content guards)
│ │ │ ├── rate_limit.py # Shared slowapi limiter (disabled in DEBUG)
│ │ │ ├── security.py # JWT + password hashing + token rotation
@@ -205,7 +224,8 @@ patherly/
│ │ │ ├── folder.py # UserFolder model
│ │ │ ├── step_category.py # StepCategory model
│ │ │ ├── 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
│ ├── alembic/ # Database migrations
│ ├── scripts/
@@ -238,11 +258,12 @@ patherly/
│ │ │ ├── treeEditorStore.ts # Tree editor state (immer + zundo)
│ │ │ └── userPreferencesStore.ts # User preferences (NEW)
│ │ ├── components/
│ │ │ ├── common/ # Modal, ErrorBoundary, ThemeToggle
│ │ │ ├── common/ # Modal, ErrorBoundary, ThemeToggle, ConfirmDialog
│ │ │ ├── layout/ # AppLayout, ProtectedRoute
│ │ │ ├── tree-editor/ # Tree editor components
│ │ │ ├── tree-preview/ # Visual tree preview
│ │ │ ├── step-library/ # Step library browser, forms, modals
│ │ │ ├── library/ # Tree library UI components
│ │ │ ├── session/ # Session modals, scratchpad floating overlay
│ │ │ └── ui/ # MarkdownContent
│ │ ├── 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.
### 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
```tsx
@@ -626,49 +657,10 @@ For detailed parameters, request/response schemas, and examples, visit the API d
## Data Models
### Tree Structure (JSONB)
Key JSONB structures stored in PostgreSQL. See `frontend/src/types/` for full TypeScript interfaces.
```typescript
interface TreeStructure {
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
}
```
- **Tree Structure:** Recursive node tree (`decision`/`action`/`solution` types with `children[]`). See `types/tree.ts`.
- **Session Decisions:** Array of `{node_id, question, answer, notes, timestamp}`. Timestamps are ISO strings, not datetime objects.
---
@@ -728,34 +720,10 @@ Position overlay at `right-2` (not `right-0`) so it sits inside the page scrollb
## Common Tasks
### Adding a New API Endpoint
1. Create route in `backend/app/api/endpoints/`
2. Add to router in `backend/app/api/router.py`
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`
- **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`
- **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`
---
@@ -798,28 +766,11 @@ Position overlay at `right-2` (not `right-0`) so it sits inside the page scrollb
### Phase 2.5 (In Progress)
- ✅ Step Categories database and API
- ✅ Step Library database schema (step_library, step_ratings, step_usage_log)
- ✅ 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
- Custom step continuation flow refinements
- Tree forking from sessions with custom steps
### Phase 3 (Planned)
- 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)
### Phase 3 — File attachments, offline mode, client context, analytics
### Phase 4 — PSA integrations (ConnectWise, Kaseya), PowerShell automation, enterprise SSO
---
@@ -933,57 +884,20 @@ Railway creates isolated preview environments for each pull request.
- Migrations run automatically via `releaseCommand`
- Domains must be generated manually for each PR service
**Debug Endpoints (available in PR environments):**
- `/debug/cors` - Check CORS configuration (allow_railway_origins, cors_mode)
**Debug Endpoints (only when `DEBUG=True`):**
- `/debug/cors` - Check CORS configuration (requires `DEBUG=True` in environment)
### Railway CLI (Local)
The Railway CLI can be installed locally for managing deployments, viewing logs, and checking service status.
**Setup on a new machine:**
Railway CLI installed via npm in project root (gitignored). Services: `patherly` (backend), `hopeful-liberation` (frontend), `Postgres` (DB).
```powershell
# 1. Install Railway CLI via npm (in 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
# Common commands (run from project root)
./node_modules/.bin/railway service status --all
# View logs
./node_modules/.bin/railway service logs --service patherly
# Check environment variables
./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