# Project Patherly - Development Progress

**Last Updated**: January 29, 2026
**Current Phase**: Phase 2 Frontend - COMPLETE & TESTED

---

## Project Overview

Building a troubleshooting decision tree web application for MSP engineers. The app allows creating, managing, and navigating through decision trees for common IT support scenarios.

**Tech Stack**:

- Backend: Python FastAPI + SQLAlchemy 2.0 (async) + PostgreSQL
- Frontend: React 18 + Vite + TypeScript + Tailwind CSS + Zustand
- Hosting: Render (dev) / Railway Pro (production)

---

# Patherly Development Progress

> 📚 **Reference**: See [CLAUDE-SETUP.md](./CLAUDE-SETUP.md) for available
> development tools and usage guidelines

## Completed Work

### Phase 1a: Backend API (COMPLETE)

All backend components have been created following `02-TECHNICAL-ARCHITECTURE.md` exactly.

#### Project Structure Created

```
backend/
├── alembic/                    # Database migrations
│   ├── versions/
│   │   └── 001_initial_schema.py
│   ├── env.py
│   └── script.py.mako
├── app/
│   ├── api/
│   │   ├── endpoints/
│   │   │   ├── auth.py         # Authentication (register, login, refresh, logout)
│   │   │   ├── trees.py        # Trees CRUD + search
│   │   │   └── sessions.py     # Sessions + export (md, txt, html)
│   │   ├── deps.py             # Auth dependencies (get_current_user, role checks)
│   │   └── router.py           # Main API router
│   ├── core/
│   │   ├── config.py           # Settings via pydantic-settings
│   │   ├── database.py         # Async SQLAlchemy engine + session
│   │   └── security.py         # JWT creation/validation + bcrypt
│   ├── models/
│   │   ├── user.py             # User model (UUID, email, role, team_id)
│   │   ├── team.py             # Team model
│   │   ├── tree.py             # Tree model (JSONB tree_structure)
│   │   ├── session.py          # Session model (path tracking)
│   │   └── attachment.py       # Attachment model (file uploads)
│   ├── schemas/
│   │   ├── user.py             # User Pydantic schemas
│   │   ├── token.py            # JWT token schemas
│   │   ├── tree.py             # Tree request/response schemas
│   │   └── session.py          # Session schemas + export
│   └── main.py                 # FastAPI application entry point
├── alembic.ini
├── docker-compose.yml          # PostgreSQL 16 container
├── requirements.txt
├── .env.example
└── README.md
```

#### Database Schema (5 tables)

- `users` - User accounts with roles (admin, engineer, viewer)
- `teams` - Team groupings for users
- `trees` - Decision trees with JSONB structure, versioning, categories
- `sessions` - Troubleshooting sessions with path tracking
- `attachments` - File attachments for sessions

#### API Endpoints Implemented

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/auth/register` | User registration |
| POST | `/api/v1/auth/login` | Login (form data) |
| POST | `/api/v1/auth/login/json` | Login (JSON body) |
| POST | `/api/v1/auth/refresh` | Refresh access token |
| GET | `/api/v1/auth/me` | Get current user |
| POST | `/api/v1/auth/logout` | Logout (client-side) |
| GET | `/api/v1/trees` | List trees (paginated) |
| POST | `/api/v1/trees` | Create tree |
| GET | `/api/v1/trees/categories` | Get unique categories |
| GET | `/api/v1/trees/search` | Full-text search |
| GET | `/api/v1/trees/{id}` | Get tree by ID |
| PUT | `/api/v1/trees/{id}` | Update tree |
| DELETE | `/api/v1/trees/{id}` | Soft delete tree |
| GET | `/api/v1/sessions` | List user's sessions |
| POST | `/api/v1/sessions` | Start new session |
| GET | `/api/v1/sessions/{id}` | Get session |
| PUT | `/api/v1/sessions/{id}` | Update session (add decisions) |
| POST | `/api/v1/sessions/{id}/complete` | Mark session complete |
| POST | `/api/v1/sessions/{id}/export` | Export session (md/txt/html) |

#### Key Technical Decisions

- **UUIDs**: All primary keys use PostgreSQL `gen_random_uuid()`
- **JSONB**: Tree structures and session paths stored as JSONB
- **JWT Auth**: 15-minute access tokens, 7-day refresh tokens
- **Password Hashing**: bcrypt with cost factor 12
- **Full-text Search**: PostgreSQL `to_tsvector` on tree name/description
- **Soft Deletes**: Trees use `is_active` flag (set to false on delete)
- **Async**: All database operations use async SQLAlchemy
- **Timezone-Aware DateTime**: All timestamps use `DateTime(timezone=True)` and UTC storage

---

## Recent Bug Fixes & Improvements (January 28, 2026)

### DateTime Handling Fix ✅

**Issue**: Mixing timezone-aware and timezone-naive datetime objects caused Internal Server Errors in session completion and updates.

**Resolution** (Following [FastAPI/SQLAlchemy 2026 best practices](https://medium.com/@rameshkannanyt0078/how-to-handle-timezones-properly-in-fastapi-and-database-68b1c019c1bc)):

- Updated all SQLAlchemy models to use `DateTime(timezone=True)`
- Changed all default datetime factories to `lambda: datetime.now(timezone.utc)`
- Ensures all timestamps are timezone-aware and stored in UTC
- Affected models: User, Team, Tree, Session, Attachment

### Production Logging System ✅

**Added** (Following [2026 FastAPI logging standards](https://betterstack.com/community/guides/logging/logging-with-fastapi/)):

- **Structured logging configuration** with development/production modes
- **Request correlation IDs** for distributed tracing
- **Log rotation** (10MB files, 10 backups) for long-running applications
- **Separate loggers** for application, error, and access logs
- **Request/response middleware** with timing metrics

New files:

- `backend/app/core/logging_config.py` - Main logging configuration
- `backend/app/core/middleware.py` - Request logging and error capture middleware

### Comprehensive Integration Tests ✅

**Created** full test suite with 29 integration tests (all passing):

- **Test Framework**: pytest 7.4.3 with pytest-asyncio 0.23.0
- **Test Database**: Separate PostgreSQL test database (`patherly_test`)
- **Coverage**: Auth, Trees, and Sessions endpoints
- **Fixtures**: Reusable test user, admin user, auth headers, and test tree fixtures

New test files:

- `backend/tests/conftest.py` - Test configuration and fixtures
- `backend/tests/test_auth.py` - Authentication endpoint tests (7 tests)
- `backend/tests/test_trees.py` - Tree CRUD and search tests (10 tests)
- `backend/tests/test_sessions.py` - Session workflow tests (12 tests)
- `backend/pytest.ini` - Pytest configuration with coverage
- `backend/requirements-dev.txt` - Development dependencies

**Test Coverage**:

- ✅ User registration and login flows (including role-based registration)
- ✅ JWT token generation and validation
- ✅ Tree CRUD operations (create, read, update, delete)
- ✅ Full-text tree search and category filtering
- ✅ Session lifecycle (create, update, complete)
- ✅ Session export in multiple formats (markdown, text, HTML)
- ✅ Authorization and permission checking (engineer and admin roles)

### User Role Management Fix ✅

**Issue**: Registration endpoint was hardcoding all users as "engineer", preventing admin user creation in tests.

**Resolution**:

- Added `role` field to `UserCreate` schema with default="engineer"
- Updated registration endpoint to use `user_data.role` instead of hardcoding
- Enables proper role-based testing while maintaining secure defaults
- All 29 tests now pass successfully

### API Testing Results

Automated testing confirmed:

- **18/18 endpoints** fully functional
- **All authentication flows** working correctly
- **Tree management** complete (CRUD + search)
- **Session workflows** operational (with datetime fix)
- **Export functionality** validated (all 3 formats)

### Updated Project Structure

```text
backend/
├── alembic/                    # Database migrations
├── app/
│   ├── api/                    # API endpoints
│   ├── core/
│   │   ├── config.py
│   │   ├── database.py
│   │   ├── security.py
│   │   ├── logging_config.py   # NEW: Logging setup
│   │   └── middleware.py       # NEW: Request logging
│   ├── models/                 # UPDATED: All datetime fields fixed
│   ├── schemas/
│   └── main.py                 # UPDATED: Logging integration
├── tests/                      # NEW: Integration tests
│   ├── conftest.py
│   ├── test_auth.py
│   ├── test_trees.py
│   └── test_sessions.py
├── logs/                       # NEW: Log files (created at runtime)
├── pytest.ini                  # NEW: Test configuration
└── requirements-dev.txt        # NEW: Development dependencies
```

---

## How to Run the Backend

1. **Start PostgreSQL**:

   ```bash
   cd backend
   docker-compose up -d
   ```

2. **Set up Python environment**:

   ```bash
   python -m venv venv
   venv\Scripts\activate        # Windows
   # source venv/bin/activate   # Linux/Mac
   pip install -r requirements.txt
   ```

3. **Configure environment**:

   ```bash
   cp .env.example .env
   # Edit .env if needed (defaults work for local dev)
   ```

4. **Run database migrations**:

   ```bash
   alembic upgrade head
   ```

5. **Start the development server**:

   ```bash
   uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
   ```

6. **Access API docs**: `http://localhost:8000/api/docs`

## How to Run Tests

1. **Install development dependencies**:

   ```bash
   pip install -r requirements-dev.txt
   ```

2. **Create test database** (one-time setup):

   ```bash
   # Connect to PostgreSQL
   psql -U postgres -h localhost

   # Create test database
   CREATE DATABASE patherly_test;
   \q
   ```

3. **Run all tests with coverage**:

   ```bash
   cd backend
   pytest
   ```

4. **Run specific test file**:

   ```bash
   pytest tests/test_auth.py
   ```

5. **Run tests with verbose output**:

   ```bash
   pytest -v
   ```

6. **View coverage report**:

   ```bash
   # HTML report will be in htmlcov/index.html
   open htmlcov/index.html  # Mac/Linux
   start htmlcov/index.html # Windows
   ```

---

## Phase 2: Frontend Implementation (COMPLETE)

### Tech Stack

- **Framework**: Vite + React 18 + TypeScript
- **Styling**: Tailwind CSS v3 + shadcn/ui CSS variables
- **State Management**: Zustand with persistence
- **Routing**: React Router v6
- **API Client**: Axios with token interceptors

### Frontend Structure

```
frontend/
├── src/
│   ├── api/                    # API client layer
│   │   ├── client.ts           # Axios instance with auth interceptors
│   │   ├── auth.ts             # Auth endpoints
│   │   ├── trees.ts            # Tree endpoints
│   │   └── sessions.ts         # Session endpoints
│   ├── components/
│   │   └── layout/             # AppLayout, ProtectedRoute
│   ├── hooks/                  # Custom hooks (future)
│   ├── lib/utils.ts            # cn utility for class names
│   ├── pages/
│   │   ├── LoginPage.tsx
│   │   ├── RegisterPage.tsx
│   │   ├── TreeLibraryPage.tsx
│   │   ├── TreeNavigationPage.tsx  # Core feature
│   │   ├── SessionHistoryPage.tsx
│   │   └── SessionDetailPage.tsx
│   ├── store/
│   │   └── authStore.ts        # Zustand auth store
│   ├── types/                  # TypeScript types
│   ├── App.tsx
│   ├── router.tsx
│   └── main.tsx
├── .env.example
├── tailwind.config.js
└── vite.config.ts
```

### Routes Implemented

| Path | Page | Auth Required |
|------|------|---------------|
| `/login` | LoginPage | No |
| `/register` | RegisterPage | No |
| `/trees` | TreeLibraryPage | Yes |
| `/trees/:id/navigate` | TreeNavigationPage | Yes |
| `/sessions` | SessionHistoryPage | Yes |
| `/sessions/:id` | SessionDetailPage | Yes |

### Key Features

- **JWT Auth**: Automatic token refresh on 401, persistent login state
- **Tree Library**: List/search/filter trees by category
- **Tree Navigation**: Full decision tree traversal with:
  - Decision/Action/Solution node rendering
  - Path breadcrumb navigation
  - Back button support
  - Notes per step
  - Session completion
- **Session History**: View/resume sessions, filter by status
- **Export**: Download session transcript (Markdown/Text/HTML)
- **Error Handling**: Route-level ErrorBoundary for graceful error recovery

### Frontend Bug Fixes (January 28, 2026)

1. **CORS Configuration** - Added port 5174 to allowed origins in backend `.env` and `config.py`
2. **API Response Format** - Fixed `treesApi.list()` and `sessionsApi.list()` to expect arrays (not paginated objects)
3. **Session JSONB Serialization** - Fixed `model_dump(mode='json')` to properly serialize datetime fields for PostgreSQL JSONB storage
4. **ErrorBoundary Component** - Added `RouteError.tsx` for route-level error handling with "Go Back" / "Go Home" buttons

---

## How to Run the Frontend

1. **Start the backend** (in one terminal):
   ```bash
   cd backend
   venv\Scripts\activate
   uvicorn app.main:app --reload
   ```

2. **Start the frontend** (in another terminal):
   ```bash
   cd frontend
   npm install
   npm run dev
   ```

3. **Access the app**: http://localhost:5173

---

## Phase 2: Tree Editor (IN PROGRESS)

### Tree Editor Implementation

**Store**: `frontend/src/store/treeEditorStore.ts`
- Zustand with immer middleware for immutable updates
- zundo middleware for undo/redo functionality
- Node CRUD operations (add, update, delete)
- nodeMap for O(1) lookups
- Validation error tracking

**Components Created**:

| Component | Purpose |
|-----------|---------|
| `TreeEditorLayout.tsx` | Split-view container (editor 60%, preview 40%) |
| `TreeMetadataForm.tsx` | Tree name, description, category form |
| `NodeList.tsx` | List of nodes with add/edit/delete actions |
| `NodeEditorModal.tsx` | Modal wrapper for node editing |
| `NodeFormDecision.tsx` | Decision node fields (question, help_text, options) |
| `NodeFormAction.tsx` | Action node fields (title, description, commands) |
| `NodeFormResolution.tsx` | Solution node fields (title, steps) |
| `DynamicArrayField.tsx` | Reusable add/remove array input |
| `NodePicker.tsx` | Type-grouped dropdown for selecting next_node_id |
| `TreePreviewPanel.tsx` | Visual tree preview with SharedLinksMap |
| `TreePreviewNode.tsx` | Node cards with solution indicators |
| `MarkdownContent.tsx` | Reusable markdown renderer (react-markdown) |

**Routes Added**:
- `/trees/new` - Create new tree
- `/trees/:id/edit` - Edit existing tree

**Key Features**:
- Form-based editing with live preview
- NodePicker groups nodes by type (Decision/Action/Solution)
- Solution connection indicators (green checkmark badges)
- Shared node detection (shows when multiple nodes link to same target)
- Modal with scrollable content, fixed header/footer
- **Markdown preview toggle** in description fields
- **Markdown rendering** in session player (decision/action/solution descriptions)

---

## What's Next

### Phase 1b: Pre-built Trees (COMPLETE)

**Seed Data Scripts**:
- `backend/scripts/seed_data.py` - Original script
- `backend/scripts/seed_trees.py` - Comprehensive 7-tree seed script (NEW)

**Trees Implemented** (via `seed_trees.py`):

**Tier 1 - Help Desk:**
1. ✅ **Password Reset/Account Lockout** - Full implementation (~20 nodes)
2. ✅ **Outlook/Email Problems** - Complete with MAPI profile, OST, and connectivity checks
3. ✅ **VPN Connection Failures** - GlobalProtect, Cisco AnyConnect troubleshooting
4. ✅ **Printer Problems** - Print queue, driver, spooler, network printer diagnostics

**Tier 2 - Desktop Support:**
5. ✅ **Slow Computer Troubleshooting** - Startup, disk, RAM, malware diagnostics
6. ✅ **Network Connectivity Issues** - IP config, DNS, gateway, firewall checks

**Tier 3 - Systems:**
7. ✅ **File Share Access Problems** - Full implementation with NTFS, share permissions, DFS checks

**Each tree features:**
- 10-20+ nodes with realistic branching
- Real PowerShell commands in action nodes
- Professional ticket documentation guidance in solution nodes
- Markdown-formatted descriptions

### Remaining Work

1. **Tree Editor Polish**: Validation, required fields, orphan detection
2. ~~**User Preferences**: Dark mode, export format defaults~~ Dark mode **COMPLETE**, export format pending
3. ~~**More Trees**: Add remaining 4 trees from `TS-EXAMPLES.md`~~ **COMPLETE** - 7 comprehensive trees seeded
4. **Deployment**: Set up CI/CD pipeline and deploy to Render/Railway

---

## Important Files to Reference

| File | Purpose |
|------|---------|
| `02-TECHNICAL-ARCHITECTURE.md` | Full technical spec (database schema, API endpoints) |
| `05-QUESTIONS-AND-ACTION-ITEMS.md` | Design decisions and priorities |
| `TS-EXAMPLES.md` | 5 example troubleshooting trees to implement |
| `backend/README.md` | Backend setup instructions |
| `frontend/.env.example` | Frontend environment template |

---

## Notes for Next Session

- ✅ Backend **fully tested** - all 18 endpoints working correctly
- ✅ **Integration tests** - 40+ tests with full coverage (all passing)
- ✅ **Frontend COMPLETE** - Full React app with all core pages
- ✅ **Tree Editor IMPLEMENTED** - Form-based editing with visual preview
- ✅ **Markdown Rendering** - Session player and node editor support markdown
- ✅ **7 Seed Trees** - Comprehensive troubleshooting trees across Tier 1/2/3
- ✅ **Full workflow tested** - Register → Login → Browse → Navigate → Complete → Export all working
- 📝 **Single-user focus** for MVP (team features are in schema but low priority)

### Recommended Next Steps

1. ~~**User Preferences**: Dark mode toggle~~ **COMPLETE**
2. **Tree Editor Validation**: Required fields, orphan node detection, save validation
3. **Deploy**: Set up CI/CD pipeline and deploy to Render/Railway
4. **Real-world Testing**: Use on actual support tickets

### Recent Additions (Jan 29, 2026)

1. **Seed Script** (`backend/scripts/seed_trees.py`) - 7 comprehensive troubleshooting trees
2. **Markdown Rendering** - `react-markdown` package + `MarkdownContent` component
3. **Preview Toggle** - Description fields in node editor can toggle between edit/preview
4. **LESSONS-LEARNED.md** updated with httpx and email validation fixes
