# TASK: Create CLAUDE.md + cleanup + statusIcon fix (felhom.eu repo) ## Context The `felhom.eu` repo lacks a CLAUDE.md with build instructions for the hub, has no `.gitignore` (so `hub.exe` got committed), and has a statusIcon rendering bug on the hub dashboard. **Current state:** Hub v0.1.2 running on k3s. Controller v0.6.2 on demo node. All changes in this task are in the **felhom.eu repo** only. --- ## Task 1: Create CLAUDE.md Create `CLAUDE.md` in the repo root (`E:\git\felhom.eu\CLAUDE.md`) with the following content. Use the controller's `CLAUDE.md` (in `deploy-felhom-compose`) as a style reference. The CLAUDE.md should include these sections: ### 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 Same as controller CLAUDE.md: - Always double-check generated code for bugs, logic issues, syntax errors - Handle edge cases without overcomplicating - Add debug capabilities for troubleshooting - Ask for more input rather than guessing ### 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. | 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 "" && 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 --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:` 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:" ``` #### 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 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 192.168.0.180 "cd ~/build/felhom-hub && ./build.sh --push"` | Build server | | 3. Deploy | `ssh 192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=...:"` | Build server (kubectl) | | 4. Verify | `ssh 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 "" && 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/.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 `` - 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). --- ## Task 2: Create .gitignore Create `.gitignore` in the repo root with appropriate entries: ```gitignore # Go binaries hub/hub hub/hub.exe hub/bin/ # Build artifacts *.exe *.dll *.so *.dylib # Test and coverage *.test *.out coverage.html # IDE .idea/ .vscode/ *.swp *.swo *~ # OS .DS_Store Thumbs.db # Temporary files *.tmp *.bak ``` ## Task 3: Remove hub.exe from git history After creating `.gitignore`, remove the committed binary: ```bash git rm --cached hub/hub.exe ``` This removes it from tracking but the `.gitignore` prevents re-adding. No need to rewrite history — just remove from current tree. Also check for any other binaries that shouldn't be tracked: ```bash find hub/ -name "*.exe" -o -name "hub" -type f -executable ``` ## Task 4: Fix hub statusIcon rendering **File:** `hub/internal/web/server.go` **Problem:** `statusIcon()` returns HTML entities (`🟢`), but Go's `html/template` auto-escapes them to literal text (`&#x1F7E2;`). Additionally, emoji don't respond to CSS `color` — but the templates already apply `style="color: {{statusColor .OverallStatus}}"`. **Fix:** Change `statusIcon()` to return `●` (U+25CF, BLACK CIRCLE) — a plain Unicode character that responds to CSS color styling. The existing `statusColor()` function handles color differentiation. ```go // BEFORE (broken): func statusIcon(status string) string { switch status { case "ok": return "🟢" // green circle case "warn": return "🟡" // yellow circle case "down", "fail": return "🔴" // red circle default: return "⚪" // white circle } } // AFTER (works with CSS color): func statusIcon(status string) string { return "●" } ``` No template changes needed — `statusColor()` already provides the correct color per status. **Verification:** 1. Dashboard: colored dot (green/yellow/red) before customer name, no `&#x` text 2. Customer detail: colored dot in header 3. Colors match status (green=OK, yellow=WARN, red=DOWN) --- ## Build & Deploy After all changes, commit and deploy hub v0.1.3: ```bash # 1. Commit cd /e/git/felhom.eu git add -A && git commit -m "add CLAUDE.md, .gitignore, fix statusIcon rendering" && git push # 2. Build ssh kisfenyo@192.168.0.180 "cd ~/build/felhom-hub && ./build.sh 0.1.3 --push" # 3. Deploy ssh kisfenyo@192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=gitea.dooplex.hu/admin/felhom-hub:0.1.3" # 4. Verify ssh kisfenyo@192.168.0.180 "sudo kubectl rollout status -n felhom-system deploy/hub && sudo kubectl logs -n felhom-system -l app=hub --tail 5" ``` ## Post-deploy checklist - [ ] `hub.felhom.eu` shows colored `●` dot, not `🟢` text - [ ] `hub.exe` no longer in repo (`git ls-files hub/hub.exe` returns empty) - [ ] `CLAUDE.md` exists in repo root - [ ] `.gitignore` exists in repo root