# Headquarter API

The backend API for Headquarter - a self-hosted platform for managing projects, git repositories, and development tools.

## Overview

Built with **FastAPI** and **SQLAlchemy** (async), using **PostgreSQL** for data storage and **Docker** for tool instance management.

### Tech Stack

- **Framework**: FastAPI (Python 3.12+)
- **Database**: PostgreSQL 15+ with asyncpg
- **ORM**: SQLAlchemy 2.0 (async)
- **Auth**: OAuth2 via Authentik with session cookies
- **Migrations**: Alembic
- **Tools**: Docker Compose for instance management

## Quick Start

### Prerequisites

- Python 3.12+
- PostgreSQL 15+ running locally
- Docker (for tool instances)

### Setup

```bash
cd apps/api

# Create virtual environment
python -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -e ".[dev]"

# Set up database
# Ensure PostgreSQL is running with a 'headquarter' database

# Run migrations
alembic upgrade head

# Start development server
uvicorn src.main:app --reload --port 8000
```

The API will be available at `http://localhost:8000`.

### Interactive Documentation

Once running, visit:
- **Swagger UI**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
- **OpenAPI JSON**: http://localhost:8000/openapi.json

## Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `DATABASE_URL` | Yes | - | PostgreSQL connection string |
| `API_BASE_URL` | Yes | - | Public API URL (e.g., `https://api.example.com`) |
| `AUTHENTIK_DOMAIN` | Yes | - | Authentik server domain |
| `AUTHENTIK_CLIENT_ID` | Yes | - | OAuth2 client ID |
| `AUTHENTIK_CLIENT_SECRET` | Yes | - | OAuth2 client secret |
| `AUTHENTIK_APPLICATION_SLUG` | Yes | - | Authentik application slug |
| `WEB_BASE_URL` | Yes | - | Public frontend URL |
| `SESSION_SECRET` | Yes | - | Secret for session cookie signing |
| `COOKIE_DOMAIN` | No | - | Cookie domain (e.g., `.example.com`) |
| `UPLOAD_DIR` | No | `./uploads` | Directory for file uploads |
| `REPO_BASE_PATH` | No | `./repositories` | Base path for git repositories |
| `INSTANCES_BASE_PATH` | No | `./instances` | Base path for tool instances |
| `LOG_LEVEL` | No | `INFO` | Logging level |

## Development

### Running Tests

```bash
# Run all tests
pytest

# Run specific test category
pytest -m unit          # Unit tests (no DB)
pytest -m integration   # Integration tests (requires DB)

# Run with coverage
pytest --cov=src --cov-report=html
```

### Code Quality

```bash
# Format code
ruff format src tests

# Lint
ruff check src tests

# Type check
mypy src
```

### Database Migrations

```bash
# Create new migration
alembic revision --autogenerate -m "description"

# Apply migrations
alembic upgrade head

# Rollback one migration
alembic downgrade -1

# Show current revision
alembic current
```

## Architecture

### Directory Structure

```
src/
├── api/              # API endpoint routers
│   ├── auth.py       # OAuth2 authentication
│   ├── dashboard.py  # Dashboard summary
│   ├── git_repositories.py  # Git repo management
│   ├── health.py     # Health checks
│   ├── projects.py   # Project CRUD
│   ├── ssh_keys.py   # SSH key management
│   ├── terminal.py   # WebSocket terminal
│   ├── tool_instances.py  # Tool instance management
│   ├── tool_types.py # Tool type definitions
│   ├── user_config.py # User preferences
│   └── users.py      # User profile
├── auth/             # Authentication logic
│   ├── cookies.py    # Cookie utilities
│   ├── dependencies.py # Auth dependencies
│   ├── oidc.py       # OpenID Connect
│   └── session.py    # Session management
├── config.py         # Application settings
├── database.py       # Database setup
├── main.py           # FastAPI application
├── models/           # SQLAlchemy models
├── schemas/          # Pydantic schemas
├── services/         # Business logic
│   ├── docker.py     # Docker Compose management
│   ├── terminal_manager.py  # Terminal sessions
│   └── terminal_session.py  # Terminal I/O
└── utils/            # Utilities
    ├── git_control.py      # Git operations
    ├── git_files.py        # File operations
    ├── git_history.py      # History extraction
    └── git_url_parser.py   # URL parsing
```

### Authentication Flow

1. User clicks "Login" → redirects to Authentik OAuth
2. Authentik redirects back with authorization code
3. API exchanges code for tokens and fetches user info
4. API creates session cookie (HMAC-signed, httpOnly)
5. Frontend stores nothing - cookie sent automatically
6. Subsequent requests include cookie for authentication

### Data Flow

```
Client → FastAPI Router → Auth Dependency → Service Layer → Database
                ↓
         Pydantic Models (validation)
                ↓
         SQLAlchemy Models (ORM)
                ↓
         PostgreSQL (storage)
```

## API Endpoints

### Authentication
- `GET /auth/login` - Initiate OAuth login
- `GET /auth/callback` - OAuth callback
- `GET /auth/me` - Get current user
- `POST /auth/logout` - Logout

### Projects
- `GET /projects` - List projects
- `POST /projects` - Create project
- `GET /projects/{id}` - Get project
- `PUT /projects/{id}` - Update project
- `DELETE /projects/{id}` - Delete project

### Git Repositories
- `GET /projects/{id}/repositories` - List repositories
- `POST /projects/{id}/repositories` - Create repository
- `GET /projects/{id}/repositories/{id}` - Get repository
- `DELETE /projects/{id}/repositories/{id}` - Delete repository
- `GET /projects/{id}/repositories/{id}/files` - List files
- `GET /projects/{id}/repositories/{id}/files/content` - Get file content
- `POST /projects/{id}/repositories/{id}/files/content` - Update file
- `GET /projects/{id}/repositories/{id}/branches` - List branches
- `GET /projects/{id}/repositories/{id}/history` - Commit history
- `GET /projects/{id}/repositories/{id}/commits/{hash}` - Commit detail

### Tool Types
- `GET /tool-types` - List tool types
- `POST /tool-types` - Create tool type
- `GET /tool-types/{id}` - Get tool type
- `PUT /tool-types/{id}` - Update tool type
- `DELETE /tool-types/{id}` - Delete tool type

### Tool Instances
- `GET /tool-instances` - List instances
- `POST /tool-instances` - Create instance
- `GET /tool-instances/{id}` - Get instance
- `POST /tool-instances/{id}/start` - Start instance
- `POST /tool-instances/{id}/stop` - Stop instance
- `POST /tool-instances/{id}/restart` - Restart instance
- `DELETE /tool-instances/{id}` - Delete instance
- `GET /tool-instances/{id}/logs` - Get logs

### Terminal
- `WS /ws/tool-instances/{id}/terminal` - WebSocket terminal

### Users
- `GET /users/me` - Get profile
- `PUT /users/me` - Update profile
- `POST /users/me/avatar` - Upload avatar
- `GET /users/me/config` - Get config
- `PATCH /users/me/config` - Update config

### SSH Keys
- `GET /ssh-keys` - List keys
- `POST /ssh-keys` - Create key
- `DELETE /ssh-keys/{id}` - Delete key

### Health
- `GET /health` - System health
- `GET /health/db` - Database health

## Deployment

See the [deployment documentation](../../docs/deployment/) for Docker and Traefik setup.

## Contributing

1. Follow PEP 8 style guide
2. Add tests for new endpoints
3. Update documentation
4. Run quality gates before committing
