# CLAUDE.md — Project Instructions for Claude Code

> This file is read automatically by Claude Code at the start of every session.
> It replaces the "Instructions" panel from the claude.ai Project.
> Keep it updated as the project evolves.

## Project overview

This repo (`felhom.eu`) contains:
- **Website** (`website/`) — Static HTML pages at felhom.eu, served via k3s nginx + git-sync sidecar
- **Hub** (`hub/`) — Go application (felhom-hub) — centralized dashboard for monitoring customer controllers, runs on k3s at hub.felhom.eu
- **K8s manifests** (`manifests/`) — k3s deployment manifests for all felhom-system services

See `README.md` for full architecture, DNS, email, and SEO documentation.
See `TASK.md` for the current task to implement (if it exists).

## Code quality rules

- Always double-check generated code for bugs, logic issues, syntax errors
- Handle edge cases without overcomplicating the script/program
- Add debug capabilities (logging, verbose output) for easier troubleshooting
- If you need more input or troubleshooting command output, ask first — don't guess

## Workspace layout

```
E:\git\felhom.eu\                  (or /e/git/felhom.eu/ in Git Bash)
├── hub/                           # felhom-hub Go application
│   ├── cmd/hub/                   # Entry point (main.go)
│   ├── internal/
│   │   ├── api/                   # Report ingestion API
│   │   ├── store/                 # SQLite storage + queries
│   │   └── web/                   # Dashboard UI
│   │       ├── server.go          # Server, routing, template funcs
│   │       ├── embed.go           # go:embed for templates
│   │       └── templates/         # HTML templates + CSS
│   ├── configs/                   # Example config files
│   ├── Dockerfile
│   ├── Makefile
│   └── go.mod
├── manifests/                     # k3s deployment manifests
│   ├── hub.yaml                   # Hub deployment (hub.felhom.eu)
│   ├── webpage.yaml               # Website + FileBrowser + git-sync
│   ├── contact-mailer.yaml        # Contact form email sender
│   ├── healthchecks.yaml          # Healthchecks (status.felhom.eu)
│   └── umami.yaml                 # Analytics (stats.felhom.eu)
├── website/                       # Static HTML pages (felhom.eu)
│   ├── index.html
│   ├── alkalmazasok.html
│   ├── ... (all Hungarian, UTF-8 with BOM)
│   └── assets/                    # Logos, screenshots, OG images
├── CLAUDE.md                      # This file
├── README.md                      # Full project documentation
└── TASK.md                        # Current task (if exists)
```

Related repos (same parent directory):
```
E:\git\deploy-felhom-compose\     # felhom-controller Go app + deploy scripts
E:\git\app-catalog-felhom.eu\     # Docker Compose templates per app
E:\git\homelab-manifests\         # k3s cluster manifests (dooplex.hu services)
E:\git\misc-scripts\              # Helper scripts (build scripts, repo collector)
```

All repos hosted at `gitea.dooplex.hu/admin/`.

## SSH access

SSH key-based authentication configured. No password prompts.

**IMPORTANT — SSH binary:** Claude Code runs in Git Bash, which has its own SSH at
`/usr/bin/ssh` (= `C:\Program Files\Git\usr\bin\ssh.exe`). This binary does NOT have
access to the Windows SSH agent and will fail silently. Always use the Windows native
OpenSSH binary:

```
SSH=/c/Windows/System32/OpenSSH/ssh.exe
```

All SSH commands below use `$SSH` — set it at the start of your session.

| Host | IP | User | Role |
|------|----|------|------|
| Build server (k3s node) | 192.168.0.180 | kisfenyo | Build + push images, kubectl |
| Demo node | 192.168.0.162 | kisfenyo | Test deployment (demo-felhom.eu) |

**Note:** `kubectl` on the build server requires `sudo` (k3s kubeconfig permissions).

## Build & deploy workflow — Hub

After making code changes to `hub/`, you **MUST** build, push, and deploy the new image.
Do NOT leave code changes uncommitted or undeployed.

### Step 1: Commit and push changes

```bash
cd /e/git/felhom.eu
git add -A && git commit -m "<descriptive message>" && git push
```

### Step 2: Build + push the container image on the build server

The build server (192.168.0.180) has the build toolchain. The build script lives at
`~/build/felhom-hub/build.sh` on the build server (NOT in this repo).

First, check the current running version:
```bash
$SSH kisfenyo@192.168.0.180 "sudo kubectl get deploy -n felhom-system hub -o jsonpath='{.spec.template.spec.containers[0].image}'"
```

Then build with the next version (e.g., if current is 0.1.2, use 0.1.3):
```bash
$SSH kisfenyo@192.168.0.180 "cd ~/build/felhom-hub && ./build.sh <NEW_VERSION> --push"
```

The build script:
- Pulls latest code from Gitea (`git pull` on the felhom.eu repo)
- Copies `hub/` source to a clean build workspace
- Builds Docker image with version + build-time ldflags
- Pushes to `gitea.dooplex.hu/admin/felhom-hub:<VERSION>` and `:latest`

### Step 3: Deploy to k3s

```bash
$SSH kisfenyo@192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=gitea.dooplex.hu/admin/felhom-hub:<NEW_VERSION>"
```

### Step 4: Verify the deployment

```bash
$SSH kisfenyo@192.168.0.180 "sudo kubectl get pods -n felhom-system -l app=hub && echo '---' && sudo kubectl logs -n felhom-system -l app=hub --tail 10"
```

Should show pod Running and `[INFO] felhom-hub <VERSION> starting` in logs.

### Build workflow summary

| Step | Command | Where |
|------|---------|-------|
| 1. Commit + push | `git add -A && git commit && git push` | Local (this repo) |
| 2. Build + push image | `$SSH kisfenyo@192.168.0.180 "cd ~/build/felhom-hub && ./build.sh <VER> --push"` | Build server |
| 3. Deploy | `$SSH kisfenyo@192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=...:<VER>"` | Build server (kubectl) |
| 4. Verify | `$SSH kisfenyo@192.168.0.180 "sudo kubectl get pods -n felhom-system -l app=hub"` | Build server |

## Build & deploy workflow — Website

The website auto-deploys via git-sync sidecar. Just push to `main`:

```bash
cd /e/git/felhom.eu
git add -A && git commit -m "<message>" && git push
```

Changes are live within 1-2 minutes. No build step needed.

For emergency edits, use FileBrowser at `https://files.felhom.eu`.

## Build & deploy workflow — K8s Manifests

Manifests are applied manually:

```bash
ssh kisfenyo@192.168.0.180 "sudo kubectl apply -f /home/kisfenyo/git/felhom.eu/manifests/<manifest>.yaml"
```

Remember to `git pull` on the build server first if you pushed changes locally.

## Tech stack (Hub)

- **Language:** Go 1.24+
- **Web framework:** stdlib `net/http` + `html/template`
- **Database:** SQLite via `modernc.org/sqlite` (pure Go, no CGo)
- **Auth:** bcrypt password hash + basic auth
- **Deployment:** Docker container on k3s (felhom-system namespace)
- **Storage:** Longhorn PVC at `/data/` (SQLite DB)
- **Config:** YAML file mounted via k8s ConfigMap at `/etc/felhom-hub/hub.yaml`

## Key patterns

- Hub receives reports from customer controllers via `POST /api/v1/report` (Bearer token auth)
- Dashboard shows all customers in a table with status, CPU, memory, disk, containers, backup age
- Customer detail page shows system info, report history, full JSON report
- Status logic: OK (report < 30m), WARN (30m-1h or health=warn), DOWN (> 1h or health=fail)
- SQLite timestamps may vary in format — use `parseSQLiteTime()` for robust parsing
- Auto-refresh: dashboard and detail pages refresh every 60 seconds via `<meta http-equiv="refresh">`
- Geo-restricted to Hungary via nginx ingress annotation

## File encoding

All HTML files in `website/` are **UTF-8 with BOM**. Ensure your editor preserves this.
Hub Go source files are standard UTF-8 (no BOM).
