# ⚠️ GOLDENE REGEL — NIEMALS RATEN. IMMER LESEN. **Nicht verhandelbar. Keine Ausnahmen.** Vor jeder Entscheidung über Feldwerte, API-Shapes, Dateinamen, Funktions-Signaturen, Konfigurationsparameter oder Architektur-Details: **erst Original lesen, dann arbeiten**. - **Referenz-Backend** (Go-Patterns, Migrations, Cluster, Packaging) → `ac_search_code(project_id=6)` oder direkt `/var/www/mail-gateway` - **Referenz-UI/Bootstrap** (React/AntD, i18n, Design-System, Install-Onliner) → `ac_search_code(project_id=5)` oder direkt `/var/www/netcell-webpanel` - **Alter Docker-Stack** (nur für Feature-Scope-Referenz!) → `ac_search_code(project_id=3)` oder `/var/www/proxy-lb-waf` - **Im Zweifel → Rückfrage statt Annahme.** --- # EdgeGuard Native (`eg`) > Native Neufassung des Docker-basierten EdgeGuard-Stacks. Kein Docker, kein WAF in v1. Zielplattform: **Debian 13 (Trixie), amd64 + arm64**. Auslieferung als signiertes `.deb`. --- ## Repository & Server - **Gitea:** https://git.netcell-it.de/projekte/edgeguard-native - **SSH-Clone:** `ssh://git@git.netcell-it.de:1922/projekte/edgeguard-native.git` - **Lokal (Dev):** `/var/www/edgeguard-native` · `ssh linux@89.163.205.87` - **Architect Center:** Projekt ID **8** - **Git-Server:** git.netcell-it.de · SSH Port 1922 · `git push origin main` --- ## MCP-Tools (Architect Center) **project_id: 8** · Session: `$ARCHITECT_SESSION` · MCP-Server: `architect` ### Beim Session-Start (PFLICHT) ``` ac_recall(query="", project_id=8, session_name="$(printenv ARCHITECT_SESSION)") ac_search_code(query="", project_id=8, session_name="$(printenv ARCHITECT_SESSION)", limit=6) ``` ### Alle Tools | Tool | Wann verwenden | |------|----------------| | `ac_recall(query, project_id=8, session_name)` | Session-Start — relevante Memories laden | | `ac_search_code(query, project_id=8, session_name, limit?)` | Vor JEDEM neuen Code schreiben | | `ac_search_code_global(query, session_name, limit?)` | Suche über alle Projekte hinweg | | `ac_remember(text, category, project_id=8, session_name)` | Jede neue Erkenntnis / Entscheidung | | `ac_create_bug(title, description?, priority?, session_name?)` | Bug gefunden | | `ac_create_feature(title, description?, priority?, session_name?)` | Feature-Idee | | `ac_create_task(title, description?, priority?, status?, project_id?)` | Follow-up Arbeit | | `ac_update_task(id, status?, priority?, title?)` | Task-Status ändern | | `ac_add_decision(title, content, category?, project_id?)` | Architekturentscheidung | | `ac_notify(message, title?, type?)` | Status-Update senden | | `ac_get_project(session_name)` | project_id für Session ermitteln | | `ac_research(query, context?)` | Doku / CVE / Libraries recherchieren | | `ac_review(code, language?, focus?)` | Code-Review nach Fertigstellung | | `ac_analyze(text, question?)` | Logs / Outputs analysieren | **`ac_remember` Kategorien:** `decision` · `pattern` · `bugfix` · `convention` · `architecture` · `general` --- ## Stack | Schicht | Technologie | |---------|-------------| | **API** | Go 1.26, Gin, GORM (Queries), goose (Migrations) | | **UI** | React 19, TypeScript strict, Vite, Ant Design 6, TanStack Query 5 | | **DB** | PostgreSQL 16 (Distro-Paket), goose-Migrations in `migrations/` | | **State/HA** | KeyDB Active-Active (Redis-kompatibel) | | **Proxy/LB** | HAProxy (Distro) — TLS-Termination, L7-Routing, LB | | **VPN** | WireGuard (Kernel-Modul ab 5.6, `wireguard-tools`) | | **DNS** | Unbound (Distro) — Forwarder+Cache mit DNSSEC, Cluster-internes Split-Horizon | | **FW** | nftables (Distro) | | **Forward-Proxy** | Squid (Distro) | | **TLS** | certbot + webroot-Plugin | | **Packaging** | dpkg-deb (direkt, wie mail-gateway + netcell-webpanel) | | **Plattform** | Debian 13 Trixie · amd64 + arm64 | --- ## Nicht-Ziele (v1) - **Kein Docker** — alle Dienste nativ unter systemd - **Kein WAF** (kein Coraza, kein ModSecurity) - **Kein IDS/IPS** (kein Suricata, kein CrowdSec) - **Kein DHCP-Server** (kein Kea) - **Kein RADIUS** (kein FreeRADIUS) - **Keine Mail-Verarbeitung** (eigenes Produkt: mail-gateway) - **Nur Debian 13** — kein Ubuntu, kein Debian 12, kein RHEL --- ## Binaries & Ports | Binary | Beschreibung | Bindet | User | |--------|-------------|--------|------| | `edgeguard-api` | REST Management-API | `127.0.0.1:9443` | `edgeguard` | | `edgeguard-scheduler` | Cron-Jobs (ACME-Renew, Backup, Health) | — | `edgeguard` | | `edgeguard-ctl` | CLI: `initdb migrate cluster-join promote dump-config` | — | root/edgeguard | HAProxy terminiert TLS auf `:443`, routet per Host-Header an Backends und fällt für Management-FQDN/ACME-Webroot auf `127.0.0.1:9443` (edgeguard-api) zurück. Die Management-UI wird von edgeguard-api ausgeliefert (statisch aus `/usr/share/edgeguard/ui/` oder embedded). --- ## Build ```bash make build # Host-Architektur (amd64) make test # go test ./... make lint # golangci-lint make deb # amd64 + arm64 .deb make publish # deb + Upload Gitea Package Registry make install-local # direkt auf Dev-Server installieren (kein .deb) # UI cd management-ui && bun install && bun run build ``` --- ## Dev-Server Quickstart ```bash # Abhängigkeiten installieren sudo apt-get install -y postgresql-16 haproxy wireguard-tools squid unbound nftables certbot # API starten (ohne systemd, für Entwicklung) go run ./cmd/edgeguard-api/ # UI Dev-Server cd management-ui && bun run dev ``` --- ## Projektstruktur ``` /var/www/edgeguard-native/ ├── cmd/ │ ├── edgeguard-api/ # Management-API (Gin, 127.0.0.1:9443) │ ├── edgeguard-scheduler/ # Cron-Jobs │ └── edgeguard-ctl/ # CLI ├── internal/ │ ├── database/ # pgxpool + goose-Runner; migrations/ via go:embed │ │ └── migrations/ # SQL (goose-Format) — embedded ins Binary │ ├── models/ # GORM-Models │ ├── handlers/ # HTTP-Handler (REST) │ ├── services/ # Business-Logik │ ├── haproxy/ # Config-Generator (TLS + Routing + LB) │ ├── squid/ # Config-Generator │ ├── wireguard/ # Config-Generator │ ├── unbound/ # Config-Generator (Forwarder + Cluster-DNS) │ ├── firewall/ # nftables-Generator │ ├── cluster/ # Join/Promote/Peer-Discovery │ ├── proxy/ # Write-Proxy → Cluster-Primary │ ├── aggregator/ # Cluster-View APIs │ └── license/ # Lizenz-Validierung ├── management-ui/ # React 19 + AntD 6 (1:1 enconf-Pattern) ├── packaging/debian/ # control, postinst, postrm, systemd-Units ├── deploy/ │ ├── systemd/ # *.service, *.target, *.timer │ ├── haproxy/ # (Templates liegen jetzt neben Renderer in internal//) │ ├── squid/ # squid.conf.tpl │ ├── unbound/ # unbound.conf.tpl │ └── nftables/ # ruleset.nft.tpl ├── scripts/ │ ├── apt-repo/ # build-package.sh, publish.sh │ └── install.sh # Bootstrap curl-Onliner ├── docs/ │ └── architecture.md # Vollständige Architektur-Spec ├── go.mod ├── Makefile ├── CLAUDE.md # Diese Datei └── agent.md # Agent-Factory Pipeline ``` --- ## Key Conventions ### Go-Code - **Migrations:** goose SQL-Dateien in `internal/database/migrations/`, via `//go:embed` ins Binary — NICHT GORM AutoMigrate - **ORM:** GORM für Queries, nicht für Schema-Verwaltung - **Config-Generierung:** Template-Datei in `deploy/*/`, Generator in `internal/*/` - **Config-Reload:** `systemctl reload ` nach Config-Schreiben - **Cluster-Writes:** immer über `internal/proxy` → Primary-URL aus KeyDB `cluster:pg-primary-url` ### Packaging - `dpkg-deb` direkt (wie mail-gateway) — kein dh_make/debhelper/fpm - postinst: User anlegen → Dirs → initdb (idempotent) → migrate → systemctl - postrm purge: nur bei `purge` DB + User entfernen ### UI - 100% enconf-Pattern (netcell-webpanel/management-ui/) — keine eigenen Design-Entscheidungen - `import type` für alle Type-Imports (verbatimModuleSyntax!) - AntD 6, kein Tailwind, kein Material UI ### Auth - JWT-basiert (analog enconf), Secret in `/var/lib/edgeguard/.jwt_fingerprint` - Admin-Check: immer aus DB-User-Row, nie aus JWT-Payload --- ## Vollständige Architektur → `docs/architecture.md` --- ## Vor jeder Änderung 1. Referenz-Pattern in mail-gateway oder netcell-webpanel lesen 2. `ac_search_code` vor neuem Code — Pattern existiert meist schon 3. `make test` nach Backend-Änderungen 4. `cd management-ui && npx tsc --noEmit` nach Frontend-Änderungen