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:
186
CLAUDE.md
186
CLAUDE.md
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user