Complete rebrand from Apoklisis to Patherly
- Update all frontend branding (title, headers, login/register pages) - Update documentation (CLAUDE-SETUP, CURRENT-STATE, PROGRESS, LESSONS-LEARNED) - Update backend scripts and test configuration - Fix emoji encoding in seed scripts for Windows compatibility - Sync seed user credentials between seed_data.py and seed_trees.py - Update database references to patherly/patherly_test Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(dir /b \"C:\\\\Dev\\\\Projects\\\\Apoklisis\")",
|
||||
"Bash(dir /b \"C:\\\\Dev\\\\Projects\\\\patherly\")",
|
||||
"Bash(npm create:*)",
|
||||
"Bash(npm install:*)",
|
||||
"Bash(npx tailwindcss:*)",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Claude Code Setup Reference for Apoklisis
|
||||
# Claude Code Setup Reference for Patherly
|
||||
|
||||
This document catalogs all tools, plugins, and MCP servers available to Claude Code when developing Apoklisis, along with guidelines for their effective use.
|
||||
This document catalogs all tools, plugins, and MCP servers available to Claude Code when developing Patherly, along with guidelines for their effective use.
|
||||
|
||||
**Last Updated**: 2026-01-29
|
||||
**Project**: Apoklisis
|
||||
**Working Directory**: `c:\Dev\Projects\Apoklisis`
|
||||
**Project**: Patherly
|
||||
**Working Directory**: `c:\Dev\Projects\patherly`
|
||||
**Platform**: Windows (win32)
|
||||
**IDE**: VSCode with Claude Code extension
|
||||
|
||||
@@ -289,8 +289,8 @@ These tools must be loaded via ToolSearch before use.
|
||||
|
||||
**Connection Details**:
|
||||
|
||||
- **Connection String**: `postgresql://postgres:postgres@localhost:5432/apoklisis`
|
||||
- **Container Name**: `apoklisis_postgres`
|
||||
- **Connection String**: `postgresql://postgres:postgres@localhost:5432/patherly`
|
||||
- **Container Name**: `patherly_postgres`
|
||||
- **Database Version**: PostgreSQL 16 Alpine
|
||||
- **Docker Requirement**: Docker Desktop must be running
|
||||
|
||||
@@ -362,11 +362,11 @@ curl -X GET "http://localhost:8000/api/v1/trees" -H "Authorization: Bearer <toke
|
||||
|
||||
---
|
||||
|
||||
## Project-Specific Context: Apoklisis
|
||||
## Project-Specific Context: Patherly
|
||||
|
||||
### Project Overview
|
||||
|
||||
**Apoklisis** is a troubleshooting decision tree web application designed for MSP (Managed Service Provider) engineers. The application allows engineers to create, manage, and navigate through decision trees for common IT support scenarios, improving troubleshooting consistency and efficiency.
|
||||
**Patherly** is a troubleshooting decision tree web application designed for MSP (Managed Service Provider) engineers. The application allows engineers to create, manage, and navigate through decision trees for common IT support scenarios, improving troubleshooting consistency and efficiency.
|
||||
|
||||
### Technology Stack
|
||||
|
||||
@@ -378,7 +378,7 @@ curl -X GET "http://localhost:8000/api/v1/trees" -H "Authorization: Bearer <toke
|
||||
- **Authentication**: JWT tokens (15-min access, 7-day refresh)
|
||||
- **Password Hashing**: bcrypt (via passlib, pinned to 4.1.2 for compatibility)
|
||||
- **API Endpoints**: 18 RESTful endpoints
|
||||
- **Containerization**: Docker (apoklisis_postgres container)
|
||||
- **Containerization**: Docker (patherly_postgres container)
|
||||
- **Migrations**: Alembic
|
||||
|
||||
**Frontend (Complete + Tree Editor)**:
|
||||
@@ -543,10 +543,10 @@ uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
**Database Connection**:
|
||||
|
||||
- **Host**: localhost:5432
|
||||
- **Database**: apoklisis
|
||||
- **Database**: patherly
|
||||
- **User**: postgres
|
||||
- **Password**: postgres
|
||||
- **Container**: apoklisis_postgres
|
||||
- **Container**: patherly_postgres
|
||||
|
||||
### Recent Work & Git History
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ frontend/
|
||||
|
||||
### Documentation
|
||||
```
|
||||
Apoklisis/
|
||||
patherly/
|
||||
├── CLAUDE-SETUP.md # Full context for Claude Code
|
||||
├── CURRENT-STATE.md # This file - quick status
|
||||
├── LESSONS-LEARNED.md # Bugs and fixes reference
|
||||
@@ -169,15 +169,15 @@ Apoklisis/
|
||||
### Start Development
|
||||
```powershell
|
||||
# Terminal 1: Database
|
||||
docker start apoklisis_postgres
|
||||
docker start patherly_postgres
|
||||
|
||||
# Terminal 2: Backend
|
||||
cd C:\Dev\Projects\Apoklisis\backend
|
||||
cd C:\Dev\Projects\patherly\backend
|
||||
.\venv\Scripts\activate
|
||||
uvicorn app.main:app --reload
|
||||
|
||||
# Terminal 3: Frontend
|
||||
cd C:\Dev\Projects\Apoklisis\frontend
|
||||
cd C:\Dev\Projects\patherly\frontend
|
||||
npm run dev
|
||||
```
|
||||
|
||||
@@ -188,7 +188,7 @@ npm run dev
|
||||
|
||||
### Run Tests
|
||||
```powershell
|
||||
cd C:\Dev\Projects\Apoklisis\backend
|
||||
cd C:\Dev\Projects\patherly\backend
|
||||
.\venv\Scripts\activate
|
||||
pytest
|
||||
```
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
### Database Name Mismatch After Fresh Clone
|
||||
**Problem:** After cloning the repo and running `docker-compose up -d`, Alembic migrations fail with `database "decision_tree" does not exist`.
|
||||
|
||||
**Cause:** The `.env` file contains the old database name (`decision_tree`) but `docker-compose.yml` creates a database called `apoklisis`.
|
||||
**Cause:** The `.env` file contains the old database name (`decision_tree`) but `docker-compose.yml` creates a database called `patherly`.
|
||||
|
||||
**Solution:** Update `.env` to use the correct database name:
|
||||
```
|
||||
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/apoklisis
|
||||
DATABASE_URL_SYNC=postgresql://postgres:postgres@localhost:5432/apoklisis
|
||||
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/patherly
|
||||
DATABASE_URL_SYNC=postgresql://postgres:postgres@localhost:5432/patherly
|
||||
```
|
||||
|
||||
**Files affected:** `backend/.env`
|
||||
@@ -57,7 +57,7 @@ When setting up development on a new machine:
|
||||
1. **Clone repo:** `git clone <repo-url>`
|
||||
2. **Start Docker Desktop**
|
||||
3. **Start database:** `cd backend && docker-compose up -d`
|
||||
4. **Fix .env database name** if it says `decision_tree` → change to `apoklisis`
|
||||
4. **Fix .env database name** if it says `decision_tree` → change to `patherly`
|
||||
5. **Create venv:** `python -m venv venv`
|
||||
6. **Activate venv:** `.\venv\Scripts\Activate`
|
||||
7. **Install backend deps:** `pip install -r requirements.txt`
|
||||
@@ -422,13 +422,13 @@ module.exports = {
|
||||
**Solution:** Use Docker exec to run psql inside the container:
|
||||
```powershell
|
||||
# Single command
|
||||
docker exec -it apoklisis_postgres psql -U postgres -c "SELECT * FROM users;"
|
||||
docker exec -it patherly_postgres psql -U postgres -c "SELECT * FROM users;"
|
||||
|
||||
# Interactive session
|
||||
docker exec -it apoklisis_postgres psql -U postgres
|
||||
docker exec -it patherly_postgres psql -U postgres
|
||||
|
||||
# Create database
|
||||
docker exec -it apoklisis_postgres psql -U postgres -c "CREATE DATABASE apoklisis_test;"
|
||||
docker exec -it patherly_postgres psql -U postgres -c "CREATE DATABASE patherly_test;"
|
||||
```
|
||||
|
||||
---
|
||||
@@ -439,7 +439,7 @@ docker exec -it apoklisis_postgres psql -U postgres -c "CREATE DATABASE apoklisi
|
||||
**Solution:** Check and start the container:
|
||||
```powershell
|
||||
docker ps # See running containers
|
||||
docker start apoklisis_postgres # Start if stopped
|
||||
docker start patherly_postgres # Start if stopped
|
||||
```
|
||||
|
||||
---
|
||||
@@ -451,7 +451,7 @@ docker start apoklisis_postgres # Start if stopped
|
||||
|
||||
**Solution:** Always run git commands from project root:
|
||||
```powershell
|
||||
cd C:\Dev\Projects\Apoklisis
|
||||
cd C:\Dev\Projects\patherly
|
||||
git add .
|
||||
git commit -m "Your message"
|
||||
git push origin main
|
||||
@@ -512,7 +512,7 @@ decision = {
|
||||
|
||||
**One-time setup:**
|
||||
```powershell
|
||||
docker exec -it apoklisis_postgres psql -U postgres -c "CREATE DATABASE apoklisis_test;"
|
||||
docker exec -it patherly_postgres psql -U postgres -c "CREATE DATABASE patherly_test;"
|
||||
```
|
||||
|
||||
**Run tests:**
|
||||
@@ -560,7 +560,7 @@ pip install httpx
|
||||
**Solution:** Use a standard domain like `example.com` for seed/test users:
|
||||
```python
|
||||
# BAD
|
||||
"email": "seed.admin@apoklisis.local"
|
||||
"email": "seed.admin@patherly.local"
|
||||
|
||||
# GOOD
|
||||
"email": "seed.admin@example.com"
|
||||
|
||||
@@ -14,7 +14,7 @@ Use this for personal thoughts, todos, and reminders.
|
||||
- [ ] Answer the 5 key questions in docs/05-QUESTIONS-AND-ACTION-ITEMS.md
|
||||
- [ ] Decide on app name (TroubleTree? DecisionPath? MSP Navigator?)
|
||||
- [ ] Set up Render account for free tier testing
|
||||
- [ ] Add Apoklisis.com to my namecheap account for dynamic dns
|
||||
- [ ] Add patherly.com to my namecheap account for dynamic dns
|
||||
|
||||
## 💡 Feature Ideas (Future)
|
||||
|
||||
|
||||
@@ -434,7 +434,7 @@ Public and team steps can be rated by users to help surface the most helpful con
|
||||
│ ○ 🌍 Public - Submit to community library │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐│
|
||||
│ │ 🔗 https://apoklisis.app/tree/abc123xyz ││
|
||||
│ │ 🔗 https://patherly.app/tree/abc123xyz ││
|
||||
│ │ [📋 Copy] ││
|
||||
│ └─────────────────────────────────────────────────────────┘│
|
||||
│ │
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Project Apoklisis - Development Progress
|
||||
# Project Patherly - Development Progress
|
||||
|
||||
**Last Updated**: January 29, 2026
|
||||
**Current Phase**: Phase 2 Frontend - COMPLETE & TESTED
|
||||
@@ -17,7 +17,7 @@ Building a troubleshooting decision tree web application for MSP engineers. The
|
||||
|
||||
---
|
||||
|
||||
# Apoklisis Development Progress
|
||||
# Patherly Development Progress
|
||||
|
||||
> 📚 **Reference**: See [CLAUDE-SETUP.md](./CLAUDE-SETUP.md) for available
|
||||
> development tools and usage guidelines
|
||||
@@ -146,7 +146,7 @@ New files:
|
||||
**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 (`apoklisis_test`)
|
||||
- **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
|
||||
|
||||
@@ -272,7 +272,7 @@ backend/
|
||||
psql -U postgres -h localhost
|
||||
|
||||
# Create test database
|
||||
CREATE DATABASE apoklisis_test;
|
||||
CREATE DATABASE patherly_test;
|
||||
\q
|
||||
```
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[pytest]
|
||||
# Pytest configuration for Apoklisis backend tests
|
||||
# Pytest configuration for Patherly backend tests
|
||||
|
||||
# Python path - add current directory so 'app' module can be imported
|
||||
pythonpath = .
|
||||
|
||||
@@ -1 +1 @@
|
||||
# Apoklisis scripts package
|
||||
# Patherly scripts package
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Seed data script for Apoklisis decision trees.
|
||||
Seed data script for Patherly decision trees.
|
||||
|
||||
This script creates example troubleshooting trees in the database.
|
||||
Run from the backend directory with: python -m scripts.seed_data
|
||||
@@ -276,7 +276,7 @@ def get_password_reset_tree() -> dict[str, Any]:
|
||||
{
|
||||
"id": "resolution_success",
|
||||
"type": "solution",
|
||||
"title": "✅ Password Reset Complete",
|
||||
"title": "[OK] Password Reset Complete",
|
||||
"description": "User has successfully logged in with their new password.\n\n**Final Steps:**\n1. Confirm user was prompted to change their password\n2. Verify user successfully set a new personal password\n3. Document the resolution in the ticket\n4. Close the ticket as 'Resolved'\n\n**Resolution Indicators:**\n- User confirms successful login\n- Account shows updated 'Last Logon' timestamp\n- No subsequent lockouts or reset requests"
|
||||
}
|
||||
]
|
||||
@@ -386,7 +386,7 @@ async def create_tree(client: httpx.AsyncClient, token: str, tree_data: dict) ->
|
||||
existing_trees = list_response.json()
|
||||
for tree in existing_trees:
|
||||
if tree["name"] == tree_data["name"]:
|
||||
print(f" ⏭️ Tree '{tree_data['name']}' already exists (ID: {tree['id']})")
|
||||
print(f" [SKIP] Tree '{tree_data['name']}' already exists (ID: {tree['id']})")
|
||||
return tree
|
||||
|
||||
# Create the tree
|
||||
@@ -400,13 +400,13 @@ async def create_tree(client: httpx.AsyncClient, token: str, tree_data: dict) ->
|
||||
raise Exception(f"Failed to create tree '{tree_data['name']}': {response.text}")
|
||||
|
||||
tree = response.json()
|
||||
print(f" ✅ Created tree '{tree_data['name']}' (ID: {tree['id']})")
|
||||
print(f" [OK] Created tree '{tree_data['name']}' (ID: {tree['id']})")
|
||||
return tree
|
||||
|
||||
|
||||
async def seed_database():
|
||||
"""Main seeding function."""
|
||||
print("\n🌱 Apoklisis Database Seeder")
|
||||
print("\n[*] Patherly Database Seeder")
|
||||
print("=" * 50)
|
||||
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
@@ -414,25 +414,25 @@ async def seed_database():
|
||||
try:
|
||||
health_check = await client.get(f"{API_BASE_URL.replace('/api/v1', '')}/health")
|
||||
except httpx.ConnectError:
|
||||
print("\n❌ Error: Cannot connect to API server")
|
||||
print("\n[ERROR] Error: Cannot connect to API server")
|
||||
print(f" Make sure the server is running at {API_BASE_URL}")
|
||||
print(" Run: uvicorn app.main:app --reload")
|
||||
return False
|
||||
|
||||
# Get or create admin user
|
||||
print("\n📋 Setting up seed user...")
|
||||
print("\n[1/2] Setting up seed user...")
|
||||
try:
|
||||
token, user_info = await get_or_create_admin_user(client)
|
||||
if user_info.get("exists"):
|
||||
print(" ✅ Using existing seed admin user")
|
||||
print(" [OK] Using existing seed admin user")
|
||||
else:
|
||||
print(f" ✅ Created seed admin user: {SEED_USER['email']}")
|
||||
print(f" [OK] Created seed admin user: {SEED_USER['email']}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Failed to setup seed user: {e}")
|
||||
print(f" [ERROR] Failed to setup seed user: {e}")
|
||||
return False
|
||||
|
||||
# Create trees
|
||||
print("\n🌳 Creating decision trees...")
|
||||
print("\n[2/2] Creating decision trees...")
|
||||
|
||||
trees_to_create = [
|
||||
get_password_reset_tree(),
|
||||
@@ -445,11 +445,11 @@ async def seed_database():
|
||||
tree = await create_tree(client, token, tree_data)
|
||||
created_trees.append(tree)
|
||||
except Exception as e:
|
||||
print(f" ❌ Failed to create '{tree_data['name']}': {e}")
|
||||
print(f" [ERROR] Failed to create '{tree_data['name']}': {e}")
|
||||
|
||||
# Summary
|
||||
print("\n" + "=" * 50)
|
||||
print(f"✅ Seeding complete! Created {len(created_trees)} trees.")
|
||||
print(f"[OK] Seeding complete! Created {len(created_trees)} trees.")
|
||||
print("\nCreated trees:")
|
||||
for tree in created_trees:
|
||||
print(f" - {tree['name']} ({tree['category']})")
|
||||
@@ -458,7 +458,7 @@ async def seed_database():
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Seed the Apoklisis database with example trees")
|
||||
parser = argparse.ArgumentParser(description="Seed the Patherly database with example trees")
|
||||
parser.add_argument("--direct", action="store_true", help="Insert directly to database (not implemented)")
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
Comprehensive MSP/SMB Troubleshooting Decision Trees Seed Script.
|
||||
|
||||
This script populates Apoklisis with realistic troubleshooting decision trees
|
||||
This script populates Patherly with realistic troubleshooting decision trees
|
||||
covering common Tier 1, Tier 2, and Tier 3 support scenarios.
|
||||
|
||||
Run from the backend directory with: python -m scripts.seed_trees
|
||||
@@ -23,8 +23,8 @@ API_BASE_URL = "http://localhost:8000/api/v1"
|
||||
# Default admin user for seeding
|
||||
SEED_USER = {
|
||||
"email": "seed.admin@example.com",
|
||||
"password": "SeedAdmin2024!Secure",
|
||||
"name": "Seed Administrator",
|
||||
"password": "SeedAdmin123!",
|
||||
"name": "Seed Admin",
|
||||
"role": "admin"
|
||||
}
|
||||
|
||||
@@ -3374,7 +3374,7 @@ async def create_tree(client: httpx.AsyncClient, token: str, tree_data: dict) ->
|
||||
async def seed_database():
|
||||
"""Main seeding function."""
|
||||
print("\n" + "=" * 60)
|
||||
print(" APOKLISIS - MSP/SMB Troubleshooting Trees Seeder")
|
||||
print(" PATHERLY - MSP/SMB Troubleshooting Trees Seeder")
|
||||
print("=" * 60)
|
||||
|
||||
async with httpx.AsyncClient(timeout=60.0) as client:
|
||||
@@ -3453,7 +3453,7 @@ async def seed_database():
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Seed the Apoklisis database with MSP/SMB troubleshooting trees"
|
||||
description="Seed the Patherly database with MSP/SMB troubleshooting trees"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--api-url",
|
||||
|
||||
@@ -17,7 +17,7 @@ from app.core.config import settings
|
||||
|
||||
|
||||
# Test database URL (separate from production)
|
||||
TEST_DATABASE_URL = "postgresql+asyncpg://postgres:postgres@localhost:5432/apoklisis_test"
|
||||
TEST_DATABASE_URL = "postgresql+asyncpg://postgres:postgres@localhost:5432/patherly_test"
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Apoklisis</title>
|
||||
<title>Patherly</title>
|
||||
<script>
|
||||
// Prevent flash of wrong theme on initial load
|
||||
(function() {
|
||||
|
||||
@@ -25,7 +25,7 @@ export function AppLayout() {
|
||||
<div className="container mx-auto flex h-14 items-center justify-between px-4">
|
||||
<div className="flex items-center gap-8">
|
||||
<Link to="/trees" className="text-lg font-bold text-foreground">
|
||||
Apoklisis
|
||||
Patherly
|
||||
</Link>
|
||||
<nav className="hidden items-center gap-1 sm:flex">
|
||||
{navItems.map((item) => (
|
||||
|
||||
@@ -36,7 +36,7 @@ export function LoginPage() {
|
||||
<div className="flex min-h-screen items-center justify-center bg-background px-4">
|
||||
<div className="w-full max-w-md space-y-8">
|
||||
<div className="text-center">
|
||||
<h1 className="text-3xl font-bold tracking-tight text-foreground">Apoklisis</h1>
|
||||
<h1 className="text-3xl font-bold tracking-tight text-foreground">Patherly</h1>
|
||||
<p className="mt-2 text-muted-foreground">Sign in to your account</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ export function RegisterPage() {
|
||||
<div className="flex min-h-screen items-center justify-center bg-background px-4">
|
||||
<div className="w-full max-w-md space-y-8">
|
||||
<div className="text-center">
|
||||
<h1 className="text-3xl font-bold tracking-tight text-foreground">Apoklisis</h1>
|
||||
<h1 className="text-3xl font-bold tracking-tight text-foreground">Patherly</h1>
|
||||
<p className="mt-2 text-muted-foreground">Create your account</p>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user