# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

This is a production infrastructure for AI-Impress, running on OVH server (ubuntu@51.89.231.46). The project uses a three-tier synchronization system:

1. **Syncthing** - Real-time bidirectional sync between Mac and server (10-30 seconds)
2. **GitHub** - Version control at git@github.com:SamoilenkoVadym/OVHserver.git
3. **rsync** - Full system backup for disaster recovery

**Critical:** You work with LOCAL files on Mac at `/Volumes/SSD/Aimpress_Cloud_Prod/`. Syncthing automatically syncs changes to the server. Never SSH into the server to make changes - always work locally.

## Architecture

### Directory Structure

```
/Volumes/SSD/Aimpress_Cloud_Prod/
├── opt/                      # Main services (synced to server /opt)
│   ├── 00-infrastructure/    # Core: Traefik, PostgreSQL, Redis, Vault, RabbitMQ, Loki
│   ├── 01-security/          # Authentik (SSO), Vaultwarden
│   ├── 02-core/              # n8n (automation), Evolution API (WhatsApp), Supabase, BigBlueButton
│   ├── 03-business/          # Odoo (ERP), Outline (wiki), Documenso, Wiki.js
│   ├── 04-tools/             # Portainer, Grafana, Prometheus, Uptime Kuma
│   ├── 05-backups/           # Backup scripts and data (NOT in Git)
│   └── 06-webflow/           # Landing pages
├── data/                     # Application data (synced to server /data)
├── home/                     # Ubuntu user files (synced to server /home/ubuntu)
└── mnt/                      # Mounted disks, backups, PostgreSQL data (synced to server /mnt)
```

### Technology Stack

- **Orchestration:** Docker + Docker Compose (all services are containerized)
- **Reverse Proxy:** Traefik with automatic SSL (Let's Encrypt via Cloudflare)
- **Databases:** PostgreSQL (shared: postgres-main), Redis (redis-main), RabbitMQ
- **Secrets:** HashiCorp Vault (do NOT commit secrets)
- **SSO:** Authentik (Single Sign-On for all services)
- **Monitoring:** Prometheus + Grafana + Loki + Uptime Kuma
- **Networks:** Docker networks - `traefik-public` (external), `database-internal` (external)

### Service Dependencies

Services MUST start in this order:
1. Traefik
2. PostgreSQL, Redis, RabbitMQ
3. Vault
4. Authentik
5. All other services

## Common Development Commands

### Docker Operations

```bash
# View running containers on server
ssh ubuntu@51.89.231.46 "docker ps"

# View logs for a container
ssh ubuntu@51.89.231.46 "docker logs <container_name>"

# Restart a service (via docker-compose)
ssh ubuntu@51.89.231.46 "cd /opt/<category>/<service> && docker compose restart"

# View service status
ssh ubuntu@51.89.231.46 "cd /opt/<category>/<service> && docker compose ps"
```

### Managing Services

Each service has a `docker-compose.yml` file in its directory:
- Traefik: `/opt/00-infrastructure/traefik/docker-compose.yml`
- n8n-shared: `/opt/02-core/n8n-shared/docker-compose.yml` (includes 4 workers)
- Odoo: `/opt/03-business/odoo/docker-compose.yml`
- etc.

To deploy/update a service:
1. Edit the `docker-compose.yml` locally
2. Wait for Syncthing sync (10-30 seconds)
3. SSH to server: `ssh ubuntu@51.89.231.46 "cd /opt/<path> && docker compose up -d"`

### Syncthing Operations

```bash
# Check Syncthing status on Mac
brew services list | grep syncthing

# Check Syncthing status on server
ssh ubuntu@51.89.231.46 "systemctl --user status syncthing"

# View sync size
du -sh /Volumes/SSD/Aimpress_Cloud_Prod/{opt,data,home,mnt}

# Force rescan of a folder
ssh ubuntu@51.89.231.46 "curl -X POST http://localhost:8384/rest/db/scan?folder=opt -H 'X-API-Key: \$(grep apikey ~/.local/state/syncthing/config.xml | sed 's/.*<apikey>\(.*\)<\/apikey>.*/\1/')'"

# Check folder status via API
ssh ubuntu@51.89.231.46 "curl -s http://localhost:8384/rest/db/status?folder=opt -H 'X-API-Key: \$(grep apikey ~/.local/state/syncthing/config.xml | sed 's/.*<apikey>\(.*\)<\/apikey>.*/\1/')' | python3 -m json.tool"
```

### Backup Operations

Backup scripts are in `/opt/05-backups/scripts/`:
- `backup-full-enhanced.sh` - Comprehensive backup with auto-discovery
- Scripts use Restic for incremental backups to Cloudflare R2
- See `/opt/05-backups/SCRIPTS-REGISTRY.md` for full script inventory

### Vault Operations

```bash
# Read a secret from Vault
ssh ubuntu@51.89.231.46 "docker exec vault vault kv get secret/myapp"

# Write a secret to Vault
ssh ubuntu@51.89.231.46 "docker exec vault vault kv put secret/myapp key=value"

# List all secrets
ssh ubuntu@51.89.231.46 "docker exec vault vault kv list secret/"

# Export secrets (use with caution)
ssh ubuntu@51.89.231.46 "cd /opt/05-backups/scripts && ./export-vault-secrets.sh"
```

**Important:** Vault integration in docker-compose uses environment variables:
```yaml
environment:
  - DB_PASSWORD=${VAULT_DB_PASSWORD}  # Read from Vault via script
```

## Git Workflow

### Automated Git Hooks

**pre-commit hook:**
- Blocks commits containing `.env`, `.key`, `.pem` files
- Warns about potential secrets
- Can override with `--no-verify` (use carefully)

**post-commit hook:**
- Automatically pushes every commit to GitHub
- Works with main/master branches

### Commit Message Format

```
<type>: <short description>

<optional detailed explanation>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
```

**Types:**
- `feat:` - New feature
- `fix:` - Bug fix
- `refactor:` - Code refactoring
- `docs:` - Documentation
- `chore:` - Maintenance (configs, dependencies)
- `perf:` - Performance improvement

### What NOT to Commit

Excluded via `.gitignore`:
- Dependencies: `node_modules/`, `__pycache__/`, `venv/`
- Secrets: `.env`, `*.key`, `*.pem`, `credentials.json`
- Backups: `opt/05-backups/`, `*.sql.gz`, `*.tar.gz`
- Data: `**/docker-data/`, `**/volumes/`
- Logs: `*.log`, `logs/`
- System: `.DS_Store`, `.cache/`

## Key Configuration Patterns

### Traefik Labels

Services use Traefik labels for routing:

```yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.<service>.rule=Host(`<service>.ai-impress.com`)"
  - "traefik.http.routers.<service>.entrypoints=websecure"
  - "traefik.http.routers.<service>.tls.certresolver=cloudflare"
  - "traefik.http.services.<service>.loadbalancer.server.port=<port>"
```

### Environment Variables

Services use `.env` files (NOT committed to Git):
- Database credentials reference shared PostgreSQL: `postgres-main`
- Redis credentials reference shared Redis: `redis-main`
- Passwords stored as `${VAR_NAME}` in docker-compose.yml

### Network Configuration

Services connect to external Docker networks:
```yaml
networks:
  traefik-public:
    external: true
  database-internal:
    external: true
```

## Important Architecture Notes

### n8n Configuration

n8n-shared runs in queue mode with Redis:
- 1 main instance (n8n-shared) handles UI and API
- 4 worker instances process jobs from Redis queue
- Workers 1-2: High concurrency (20 jobs)
- Workers 3-4: Medium concurrency (15 jobs)
- Webhooks and OAuth endpoints bypass authentication for external access

### BigBlueButton Configuration

BigBlueButton is deployed for workshops and webinars:
- Multi-container setup with separate services (HTML5, Freeswitch, Kurento, etc.)
- GraphQL API for real-time data
- Integration with Odoo via `bbb_connector` addon
- Webhooks for meeting events
- Data stored in `/opt/02-core/bigbluebutton/`

### Odoo Custom Addons

Odoo supports custom addons in `/opt/03-business/odoo/extra-addons/`:
- `bbb_connector/` - BigBlueButton integration
- `virtual_meeting/` - Virtual meeting management
- Addons are automatically discovered on Odoo restart
- Add addon path to `odoo.conf`: `addons_path = /mnt/extra-addons`

### Database Architecture

- Single PostgreSQL instance (`postgres-main`) serves multiple services
- Each service has its own database (e.g., `n8n_shared`, `odoo_db`)
- Connection via `database-internal` network
- Data stored in `/mnt/psql-data/`

### SSL & Domain Management

All services use:
- Domain: `*.ai-impress.com`
- SSL via Traefik + Cloudflare DNS challenge
- Certificates stored in `/opt/00-infrastructure/traefik/acme/`

## Workflow for Claude Code

When making changes:

1. **Read** local files from `/Volumes/SSD/Aimpress_Cloud_Prod/`
2. **Edit** files locally (never SSH to make changes)
3. **Wait** 10-30 seconds for Syncthing to sync to server
4. **Commit** with descriptive message using format above
5. **Verify** changes on server if needed (via SSH to view logs/status)

When adding new services:

1. Create directory in appropriate `/opt/<category>/` folder
2. Create `docker-compose.yml` with Traefik labels
3. Create `.env` file (will be auto-ignored by Git)
4. Add to appropriate Docker networks
5. Document in project structure files
6. Test on server, then commit

## Important Security Notes

- **Never commit secrets** - pre-commit hook will block `.env` files
- **Use Vault** for sensitive credentials when possible
- **Authentik SSO** protects most admin interfaces
- **Traefik middleware** can add authentication to services
- Database passwords are in `.env` files, referenced as `${VAR_NAME}`

## Troubleshooting

### Service Won't Start

1. Check logs: `ssh ubuntu@51.89.231.46 "docker logs <container>"`
2. Verify networks exist: `ssh ubuntu@51.89.231.46 "docker network ls"`
3. Check if port is already in use
4. Verify Traefik is running first

### Syncthing Issues

1. Check status on both Mac and server
2. View sync conflicts in Syncthing UI
3. Check `.stignore` for exclusion patterns
4. Verify folder permissions

### Database Connection Issues

1. Ensure `postgres-main` container is running
2. Check `database-internal` network exists
3. Verify credentials in `.env` file
4. Check PostgreSQL logs: `ssh ubuntu@51.89.231.46 "docker logs postgres-main"`

## Reference Documentation

- Detailed structure: `.claude/project-structure.md`
- Workflow details: `.claude/workflow.md`
- Backup scripts: `opt/05-backups/SCRIPTS-REGISTRY.md`
- Main README: `README.md`

---

## 🚨 КРИТИЧЕСКИ ВАЖНО: Выбор модели

**ВСЕГДА используй Haiku (`model: "haiku"`) для:**
- ✅ Работы в терминале (Bash, ssh команды)
- ✅ Чтения и редактирования файлов (Read, Edit, Write)
- ✅ Поиска в коде (Grep, Glob)
- ✅ Работы с Docker/Git
- ✅ Отладки и исправления ошибок
- ✅ Любых практических задач по коддингу

**Используй Sonnet ТОЛЬКО для:**
- 📊 Сложного планирования архитектуры
- 📋 Анализа требований пользователя
- 🎯 Принятия стратегических решений
- 🔍 Глубокого анализа проблем

**Примеры:**
```
❌ НЕПРАВИЛЬНО: Task(subagent_type="general-purpose", prompt="собери credentials")
✅ ПРАВИЛЬНО: Task(subagent_type="general-purpose", model="haiku", prompt="собери credentials")
```