Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,32 @@ This applies to ALL work — backend, frontend, research, everything. No excepti
**Important**: This project has detailed documentation for faster development:
- **Backend Documentation**: See `backend/CLAUDE.md` for Django structure, API endpoints, models, and patterns
- **Frontend Documentation**: See `frontend/CLAUDE.md` for Svelte 5 structure, routes, components, and API integration
- **Session Management**: See `SESSIONS.md` for the Git worktree-based development session system
- **Session Management**: See `SESSIONS.md` for orca-based development sessions with Docker isolation

⚠️ **Keep documentation updated**: When making changes to the codebase, update the relevant CLAUDE.md file to help future development sessions.

## Development Sessions & Worktrees
This project uses a custom session management system with Git worktrees. See `SESSIONS.md` for complete documentation on:
- Creating and managing parallel development sessions
- Port allocation and tmux window management
- Claude Code session persistence across worktrees
- Troubleshooting common issues
## Development Sessions with Orca
This project uses [orca](https://github.com/rasca/orca) for Docker-isolated development sessions. See `SESSIONS.md` for complete documentation.

Each session gets: git worktree, Docker container, tmux session, and its own PostgreSQL database.

Quick commands:
```bash
./session-mgmt add <name> # Create new session
./session-mgmt list # Show all sessions
./session-mgmt resume [name] # Resume after restart
./session-mgmt remove <name> # Remove session
orca add <name> # Create new session
orca list # Show all sessions
orca attach <name> # Attach to tmux session
orca resume [name] # Resume after restart
orca remove <name> # Remove session
orca pr <number> # Create session from PR
```

Configuration lives in `orchestrator.yml` at the project root.

### Database
A shared PostgreSQL container (`tally-postgres`) serves all sessions:
```bash
cd backend && docker compose up -d db # Start PostgreSQL
cd backend/scripts && ./migrate-prod-to-dev.sh # Sync production data
```

## Svelte 5 Important Notes
Expand Down
265 changes: 108 additions & 157 deletions SESSIONS.md
Original file line number Diff line number Diff line change
@@ -1,184 +1,135 @@
# Points Session Management System Documentation
# Development Sessions with Orca

## Overview
The Points project uses a custom session management system that allows multiple parallel development sessions using Git worktrees, tmux, and Claude Code. Each session gets its own isolated environment with dedicated ports and persistent Claude conversations.

## Key Components
This project uses [orca](https://github.com/rasca/orca) for Docker-isolated development sessions. Each session gets its own git worktree, Docker container, tmux session, and PostgreSQL database.

### 1. The `session-mgmt` Script
Location: `/Users/rasca/Dev/tally/session-mgmt`
## Prerequisites

This is the main management script with the following commands:
- `./session-mgmt add <name>` - Creates a new session with worktree, branch, and tmux windows
- `./session-mgmt remove <name>` - Removes a session completely (worktree, branch, tmux)
- `./session-mgmt resume [name]` - Resumes session(s) after system restart
- `./session-mgmt list` - Shows all active sessions with their ports
- **orca** installed: `curl -fsSL https://raw.githubusercontent.com/rasca/orca/main/install.sh | bash`
- **Docker Desktop** running
- **orca base image** built: `orca build`

### 2. Session Structure
Each session consists of:
- **Git Worktree**: Located at `~/Dev/tally-<name>/`
- **Git Branch**: Named exactly as the session (e.g., `feature-auth`, not `session-feature-auth`)
- **Tmux Session**: Named `tally-<name>` with 5 windows:
- `backend:<port>` - Django server running on the specified port
- `frontend:<port>` - Svelte dev server running on the specified port
- `claude` - Claude Code session running in worktree root
- `shell` - Interactive shell with environment activated and ready
- `cli` - Command line ready for one-off commands (env activated, not executed)

### 3. Port Management
- Backend ports start at 8000 and increment (8001, 8002, etc.)
- Frontend ports start at 5000 and increment (5001, 5002, etc.)
- Port assignments are tracked in `.tally-sessions` file to avoid conflicts
- The script automatically finds the next available ports when creating new sessions

### 4. Session Configuration File
Location: `/Users/rasca/Dev/tally/.tally-sessions`

JSON file tracking all sessions:
```json
{
"session-name": {
"backend_port": 8000,
"frontend_port": 5000,
"worktree": "/Users/rasca/Dev/tally-session-name",
"branch": "session-name"
}
}
```
## Quick Start

```bash
# Start the shared PostgreSQL container (one-time)
cd backend && docker compose up -d db && cd ..

# Create a new session
orca add feature-auth

# Attach to the tmux session
orca attach feature-auth

# List all sessions
orca list

# Stop a session (preserves worktree + volumes)
orca stop feature-auth

# Resume after restart
orca resume feature-auth

## Automatic Setup Features

When creating a new session, the script automatically:

### 1. Creates Symlinks
- `frontend/node_modules` → symlinked to main project's node_modules (avoids reinstalling)

### 2. Copies Resources (Each Session Gets Its Own)
- `backend/db.sqlite3` → copied from main project (independent database per session)
- `backend/.env` - Copied from main project (contains SECRET_KEY and other env vars)
- `frontend/.env` - Copied from main project and updated with session-specific backend URL
- Automatically sets `VITE_API_URL=http://localhost:<backend_port>` for proper API routing

### 3. Sets Up Claude Code
- Each Claude session uses a persistent name: `tally-<session-name>`
- When resuming: uses `--resume` flag to continue previous conversation
- Working directory is set to the worktree root

### 4. Activates Virtual Environment
All commands use `workon tally` to activate the Python virtual environment before executing

## Claude Tool Permissions

### Where Permissions Are Stored
Claude Code stores tool permissions in `~/.claude.json` under the `projects` section:
```json
{
"projects": {
"/Users/rasca/Dev/tally": {
"allowedTools": [
"Bash(npm install:*)",
"Bash(python manage.py:*)",
// ... other allowed tools
]
}
}
}
# Remove everything
orca remove feature-auth
```

### Permission Inheritance Issue
Currently, each new worktree is treated as a separate project by Claude Code, so permissions need to be set up for each worktree. The script should copy the `allowedTools` array from the main project to each new worktree project in `~/.claude.json`.
## Session Structure

## Common Workflows
Each session consists of:
- **Git Worktree**: `~/Dev/tally-<name>/`
- **Git Branch**: Named after the session
- **Docker Container**: `orca-tally-<name>`
- **Tmux Session**: `tally-<name>` with windows:
- `backend:<port>` — Django server
- `frontend:<port>` — Svelte dev server
- `django-shell` — Django interactive shell
- `claude` — Claude Code session
- `shell` — Interactive shell
- `cli` — For one-off commands

## Configuration

All session configuration lives in `orchestrator.yml` at the project root. Key settings:
- **Ports**: Backend starts at 8000, frontend at 5000 (auto-incremented per session)
- **Database**: Each session gets `DATABASE_URL` set to `tally_<session-name>` database
- **Setup files**: `.env` files are copied and updated per-session automatically

## Database Management

### Architecture

A single shared PostgreSQL container serves all sessions:

### Creating a New Feature Session
```bash
./tally-session add feature-payment
tmux attach -t tally-feature-payment
# Work on your feature across backend, frontend, and Claude windows
```
Docker: tally-postgres (port 5432, postgres:17)
├── tally_main ← main worktree
├── tally_template ← production snapshot
├── tally_feature_x ← orca session
└── tally_pr_123 ← PR session
```

### Start PostgreSQL

### After System Restart
```bash
# Resume all sessions
./tally-session resume
cd backend && docker compose up -d db
```

### Sync Production Data

# Or resume specific session
./tally-session resume feature-payment
```bash
cd backend/scripts
./migrate-prod-to-dev.sh --download # Download from RDS
./migrate-prod-to-dev.sh --upload # Restore to tally_template
./migrate-prod-to-dev.sh --setup # Run migrations + create admin
```

### Cleaning Up
### Create Session Database from Template

After syncing prod data, create instant clones for new sessions:

```bash
./tally-session remove feature-payment
# This removes the worktree, branch, and kills the tmux session
docker compose -f backend/docker-compose.yml exec db \
psql -U tally_user -c 'CREATE DATABASE "tally-feature-x" TEMPLATE tally_template'
```

## Troubleshooting
### Database Status

### Port Already in Use
If you get "port already in use" errors:
1. Check `.tally-sessions` file for port assignments
2. Make sure the script's port allocation is working correctly
3. Kill any orphaned processes using `lsof -i :PORT | grep LISTEN`

### Missing Dependencies
If backend or frontend fail to start:
1. Check that `.env` files were copied correctly
2. Verify symlinks are intact (node_modules, db.sqlite3)
3. Ensure virtual environment is activated (`workon tally`)

### Claude Sessions
- Session names follow pattern: `tally-<session-name>`
- Use `--resume` flag to continue previous conversations
- Each worktree needs its own tool permissions in `~/.claude.json`

## Important Notes for Claude (AI Assistant)

When working with this system:
1. **Always use the worktree path** - Each session runs in its own worktree at `~/Dev/tally-<name>/`
2. **Port awareness** - Check `.tally-sessions` for assigned ports before suggesting localhost URLs
3. **Virtual environment** - All Python commands need `workon tally` first
4. **Independent databases** - Each session has its own database copy, changes don't affect other sessions
5. **Shared node_modules** - Node modules are symlinked to save space (read-only, shared)
6. **Git operations** - Each worktree has its own branch; commits don't affect other sessions
7. **Tool permissions** - New worktrees may need permission setup if not inherited from main project
8. **Frontend API URL** - Each session's frontend automatically points to its own backend port

## File Structure Example
```bash
docker compose -f backend/docker-compose.yml exec db \
psql -U tally_user -c "\l" | grep tally
```
~/Dev/
├── tally/ # Main repository
│ ├── backend/
│ │ ├── .env # Original env file
│ │ └── db.sqlite3 # Original database
│ ├── frontend/
│ │ ├── .env # Original env file
│ │ └── node_modules/ # Original node modules
│ ├── tally-session # Management script
│ └── .tally-sessions # Session tracking file
├── tally-feature-auth/ # Worktree for feature-auth session
│ ├── backend/
│ │ ├── .env # Copied from main
│ │ └── db.sqlite3 # Independent copy (not shared)
│ └── frontend/
│ ├── .env # Copied & updated with backend port
│ └── node_modules/ # Symlink to main (shared)
└── tally-bugfix-ui/ # Another worktree
└── ... # Same structure

## PR Reviews

```bash
orca pr 42 # Create session from PR #42
orca attach pr-42 # Attach to it
orca update-pr 42 # Pull latest changes
orca remove pr-42 # Clean up
```

## Session Commands Reference
## Port Allocation

Ports are auto-allocated globally across all orca sessions:
- Backend: 8000, 8001, 8002, ...
- Frontend: 5000, 5001, 5002, ...

Inside each tmux session, the windows and their states are:
- **backend:<port>**: Running Django server - `python manage.py runserver <port>`
- **frontend:<port>**: Running Svelte dev server - `npm run dev -- --port <port>`
- **claude**: Running Claude Code session - `claude tally-<name>` (or with `--resume`)
- **shell**: Interactive shell ready for use (environment activated, in worktree root)
- **cli**: Command line with environment ready but not executed (press Enter to run commands)
Port assignments are visible via `orca list` and in tmux window names.

## Troubleshooting

All windows have:
- Virtual environment activated: `workon tally`
- Working directory set: `cd ~/Dev/tally-<name>/[appropriate-dir]`
### Django Can't Connect to Database
1. Ensure `tally-postgres` container is running: `docker ps | grep tally-postgres`
2. Check the database exists: `docker compose -f backend/docker-compose.yml exec db psql -U tally_user -l`
3. From inside orca container, host is `host.docker.internal`, not `localhost`

The port numbers are shown in the window names for easy reference.
### Port Already in Use
Check active sessions with `orca list`. Ports are tracked in `~/.orca/sessions.json`.

### Container Won't Start
```bash
orca stop <name> # Force stop
orca resume <name> # Restart fresh
```
26 changes: 9 additions & 17 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,18 @@ DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1

# Database
# Leave DATABASE_URL empty for SQLite (development)
# For production, set to your database URL (e.g., postgres://user:pass@host:port/dbname)
DATABASE_URL=

# RDS Database Connection (for migration script)
# Required only when running migrate_rds_to_sqlite.py
# Provide database credentials in one of these ways:
#
# Option 1: Full database URL in .env
# RDS_DATABASE_URL=postgresql://username:password@host:port/database
# Local development uses a shared PostgreSQL container managed by orca.
# Each orca session gets its own database (tally_<session-name>).
# The main worktree uses tally_main.
#
# Option 2: AWS SSM Parameter Store (set parameter name)
# RDS_DATABASE_URL_PARAM=/tally/prod/database_url
# From inside orca Docker containers, use host.docker.internal to reach the host PG container.
# If running directly on host (without orca), use localhost instead.
#
# Option 3: AWS Secrets Manager (set secret name)
# RDS_SECRET_NAME=my-rds-secret
# Start the PostgreSQL container: docker compose -f backend/docker-compose.yml up -d db
DATABASE_URL=postgresql://tally_user:tally_password@host.docker.internal:5432/tally_main

# Migration Settings
# Password to set for all users when importing from RDS
RESET_PASSWORD=testpassword123
# For production, set to your RDS URL:
# DATABASE_URL=postgresql://username:password@host:port/database

# CORS and CSRF Settings
CORS_ALLOWED_ORIGINS=https://your-frontend-domain.com,https://another-domain.com
Expand Down
Loading