docs: add project log (handover notes) and CLAUDE.md pointer
ci / Go (lint, test, vuln) (push) Successful in 3m27s
ci / Protobuf (push) Successful in 6s
ci / Web (lint, test, audit, build) (push) Successful in 53s
ci / Shell and licence headers (push) Successful in 6s
ci / Release build (dry run) (push) Successful in 1m53s
ci / Development environment (compose) (push) Successful in 15s
ci / Go (lint, test, vuln) (push) Successful in 3m27s
ci / Protobuf (push) Successful in 6s
ci / Web (lint, test, audit, build) (push) Successful in 53s
ci / Shell and licence headers (push) Successful in 6s
ci / Release build (dry run) (push) Successful in 1m53s
ci / Development environment (compose) (push) Successful in 15s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a670256be6
commit
e91d1d63c0
@@ -0,0 +1,6 @@
|
||||
# Hinweise für die Arbeit an diesem Repository
|
||||
|
||||
- Auftrag: [docs/PROJECT_BRIEF.md](docs/PROJECT_BRIEF.md). Architektur: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). Entscheidungen: [docs/adr/](docs/adr/README.md).
|
||||
- **Stand, offene Punkte, nächster Schritt und Erfahrungen aus früheren Sitzungen: [docs/LOGBUCH.md](docs/LOGBUCH.md) – zuerst lesen und nach jeder Arbeitssitzung fortschreiben.**
|
||||
- Arbeitsweise nach Brief §0: in Meilensteinen, Conventional Commits, Tag erst bei grüner CI, Code/Logs Englisch (US), Doku/UI Deutsch.
|
||||
- Vor jedem Commit: `make lint` (bzw. `golangci-lint run ./...`, `scripts/check-spdx.sh`, `shellcheck`, `cd web && npm run lint && npm run typecheck`) und Tests; API-Änderungen immer zusammen mit `server/api/openapi.yaml` und `npm run gen:api`.
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
# Logbuch
|
||||
|
||||
Arbeitsprotokoll des Projekts. Es dient als Übergabe zwischen Rechnern und Sitzungen: Was ist fertig, was ist offen, was wurde unterwegs gelernt und wie geht es weiter. Fachliche Entscheidungen stehen in den [ADRs](adr/README.md), die Architektur in [ARCHITECTURE.md](ARCHITECTURE.md). Hier steht, was dort nicht hineingehört.
|
||||
|
||||
Neue Einträge oben im Abschnitt „Verlauf“ ergänzen und den Abschnitt „Stand“ aktuell halten.
|
||||
|
||||
---
|
||||
|
||||
## Stand (2026-10-12, nach M1)
|
||||
|
||||
| Meilenstein | Status | Tag |
|
||||
| --- | --- | --- |
|
||||
| M0 Fundament | fertig, CI grün | `v0.1.0` |
|
||||
| M1 Server-Kern | fertig, CI grün | `v0.2.0` |
|
||||
| M2 Config-Generator | **als Nächstes** | – |
|
||||
| M3–M6 | offen | – |
|
||||
|
||||
Branch `main`, alles gepusht nach `https://git.beugsiud.de/beug.k/DDI`. Release `v0.1.0` mit Artefakten auf Gitea veröffentlicht; `v0.2.0` ebenso über den Release-Workflow.
|
||||
|
||||
### Offene Punkte
|
||||
|
||||
1. **Live-Test mit echter Keygen-Lizenz steht aus.** Gegen `license.beugsiud.de` ist bisher nur die Antwortsignatur geprüft (ungültiger Schlüssel, `validate-key`). Ablauf: `tools/keygen-setup/keygen-setup.sh setup` (Admin-Token nur als Umgebungsvariable), Produkt-ID als `KEYGEN_PRODUCT_ID` setzen, `create-license`, Schlüssel in der Oberfläche eintragen. Zu beobachten: Aktivierung (`POST /machines` mit `License`-Auth), Entitlements, Heartbeat, Revalidierung. Das Skript selbst ist gegen die Instanz noch nie gelaufen (Produkt-Attribut `code`, Policy-Attribute ggf. an die CE-Version anpassen).
|
||||
2. **Oberfläche nie im echten Browser bedient.** Abgesichert nur durch Vitest-Komponententests und den CI-Smoke-Test des Release-Binaries (Auslieferung von `index.html`/Assets). Beim ersten Durchklicken (`make dev-up`, `make dev-admin`, `make run-server`, `cd web && npm run dev`) auf Layout-Fehler und Abläufe achten.
|
||||
3. **Frontend-Bundle groß** (~600 KB, 182 KB gzip). Code-Splitting nach Seiten (React `lazy`) einplanen.
|
||||
4. **Service-Schicht ohne eigene Abdeckungszahl:** Sie wird über die API-Tests geprüft; für einen Nachweis `go test -coverpkg=./server/... ./server/internal/httpapi` verwenden.
|
||||
5. **GitHub-Rate-Limit in der CI:** `setup-go`/`setup-node` holen Manifeste von GitHub (60 Anfragen/Stunde je IP, ohne Token). Bisher nur Warnungen mit Fallback. Falls Jobs daran scheitern: Go/Node in `scripts/ci/install-tools.sh` selbst mit Prüfsumme installieren.
|
||||
6. **TanStack Table 9 und React Router 8** sind erschienen; bewusst auf Table 8 / Router 7 geblieben. Upgrade später als eigener Schritt.
|
||||
|
||||
### Nächster Schritt: M2 (Config-Generator)
|
||||
|
||||
Laut Brief §7 und [ADR 0014](adr/0014-konfigurationserzeugung.md):
|
||||
|
||||
- Paket `server/internal/configgen`: reine Funktionen `Render(input) → Artefakte`, keine DB/Uhr/Zufall im Generator, deterministische Ausgabe.
|
||||
- Kea: typisierte Go-Structs → `encoding/json`; Subnetze, **effektive Pools** (`ipam.EffectivePools` existiert schon), Reservierungen aus `manual_dhcp`, Optionen (Router, DNS, NTP, Domain, Suchdomänen), Lease-Zeiten, `lease_cmds`-Hook, Unix-Control-Socket. Nur freie Bestandteile ([ADR 0005](adr/0005-dhcp-engine-kea.md)).
|
||||
- BIND: eigene Writer für die Include-Datei und Zonendateien der managed Zonen, A/PTR aus `static`/`manual_dhcp`, Reverse-Zonen ableiten, SOA-Serial = Revisionsnummer, strikte Validierung/Escaping (TXT in ≤255-Byte-Strings). Kein `text/template`.
|
||||
- Golden-Files unter `testdata/` mit `-update`-Flag, Fuzz-Tests für Validierer.
|
||||
- Integrationstests in `/test` gegen echte Container: `named-checkconf -z`/`named-checkzone` und `kea-dhcp4 -t`. In der CI laufen Container nur im Job mit Docker-Zugriff (Muster: Compose-Job; **keine Bind-Mounts**, Dateien per Build-Kontext oder `docker cp` in die Container bringen).
|
||||
- Für M2 fehlen noch Tabellen für Zonen/Records/Cluster/Revisionen (Migration `00002_…`); Zonenverwaltung im UI ist M5, M2 kann Zonen aus `networks.domain` ableiten.
|
||||
|
||||
---
|
||||
|
||||
## Arbeitsumgebung
|
||||
|
||||
### Werkzeuge (Versionen gepinnt)
|
||||
|
||||
| Werkzeug | Version | Hinweis |
|
||||
| --- | --- | --- |
|
||||
| Go | 1.27.2 (`go.mod`: `go 1.27.0`, `toolchain go1.27.2`) | `GOTOOLCHAIN=local` empfohlen |
|
||||
| Node.js | 24 LTS (24.21.0) | npm 11 |
|
||||
| golangci-lint | 2.14.0 | Konfiguration `.golangci.yml` (v2) |
|
||||
| buf | 1.73.0 | Remote-Plugins, braucht Netz zu `buf.build` |
|
||||
| shellcheck | 0.11.0 | |
|
||||
| jq | 1.8.x | für `scripts/release-upload.sh` |
|
||||
| Docker + Compose | aktuell | Entwicklungsumgebung, Integrationstests |
|
||||
|
||||
Unter Linux installiert `scripts/ci/install-tools.sh` golangci-lint, buf und shellcheck mit Prüfsummen.
|
||||
|
||||
### Besonderheit des ursprünglichen Windows-Rechners
|
||||
|
||||
Auf dem ersten Arbeitsplatz (verwalteter Windows-Rechner) blockiert eine Defender-ASR-Regel („Block executable files unless they meet a prevalence, age, or trusted list criterion“) das Ausführen frisch kompilierter `.exe`. Folgen:
|
||||
|
||||
- Go-Tests, `go run`, `go tool …` und lokal gebaute Plugins laufen dort **nicht**. Möglich sind `go build`, `go vet`, `golangci-lint`, `go test -exec=true ./...` (nur kompilieren), `buf` mit Remote-Plugins, alles mit Node (Vitest, ESLint, Vite, openapi-typescript).
|
||||
- Kein Docker, kein WSL, kein `make`. Die Make-Ziele wurden deshalb dort nie direkt ausgeführt, sondern ihre Befehle einzeln; die CI führt `make` aus.
|
||||
- Werkzeuge lagen portabel in `%LOCALAPPDATA%\ddi-tools` (Go, Node, golangci-lint, shellcheck, buf, jq) mit `GOTMPDIR` dort.
|
||||
- Die Regel nicht umgehen. Auf einem Linux-Rechner (oder mit Ausnahme durch die IT) gilt nichts davon: `make ci` läuft dort komplett.
|
||||
|
||||
### Nützliche Befehle
|
||||
|
||||
```sh
|
||||
make help # Übersicht
|
||||
make ci # Lint, generierter Code, Tests, Schwachstellen, Build
|
||||
make dev-up # PostgreSQL, BIND, Kea (Docker)
|
||||
make dev-admin # erster Admin in der Dev-DB (Einmal-Passwort)
|
||||
make run-server # Server auf http://127.0.0.1:8080, Konfig deploy/config/server.dev.yaml
|
||||
cd web && npm run dev # UI mit Hot Reload (Proxy auf :8080)
|
||||
make generate # Protobuf + TypeScript-API-Typen neu erzeugen
|
||||
make release # Tarballs + SHA256SUMS nach dist/
|
||||
```
|
||||
|
||||
Datenbanktests brauchen `DDI_TEST_DATABASE_URL` (z. B. `postgres://ddi:ddi-dev-only@127.0.0.1:5432/ddi?sslmode=disable`); jeder Test bekommt ein eigenes Schema. Ohne Variable werden sie übersprungen, in der CI erzwingt `DDI_REQUIRE_DB_TESTS=1` sie.
|
||||
|
||||
---
|
||||
|
||||
## CI und Git-Host
|
||||
|
||||
- **Gitea 1.27.2** (kein Forgejo/GitLab), Actions unter `.gitea/workflows/`. Das automatische Job-Token reicht für Releases.
|
||||
- Job-Logs sind öffentlich: `https://git.beugsiud.de/beug.k/DDI/actions/runs/<run>/jobs/<job>/logs`. Status eines Commits ohne Token: `GET /api/v1/repos/beug.k/DDI/commits/<sha>/status`. `/actions/runs` braucht ein Token.
|
||||
- `concurrency: cancel-in-progress` – ein neuer Push bricht laufende Jobs ab, sie erscheinen dann als „failure“. Im Log nach `Job cancelled` sehen, bevor man einen Fehler sucht.
|
||||
- Der Docker-Daemon der Runner ist geteilt: **keine festen Subnetze, keine festen Host-Ports, keine Bind-Mounts** in Compose-Dateien für die CI (Projektname pro Lauf: `COMPOSE_PROJECT_NAME=ddi-ci-<run_id>`).
|
||||
- Pushes scheitern gelegentlich einmal mit „Failed to authenticate user“; ein zweiter Versuch klappt. Erstes Push auf einem neuen Rechner erfolgt interaktiv über den Credential Manager (bei 2FA mit Zugriffstoken).
|
||||
- Jobs: Go (Lint, Tests mit Race-Detector und PostgreSQL-Service, govulncheck), Protobuf, Web (generierte API-Typen aktuell, ESLint, Typecheck, Tests, npm audit, Build), Shell/SPDX, Release-Probebau mit Smoke-Test des echten Binaries, Compose-Smoke-Test.
|
||||
|
||||
---
|
||||
|
||||
## Konventionen (Kurzfassung)
|
||||
|
||||
- Code, Kommentare, Commits, Logs, API-Felder: **Englisch (US-Schreibweise, `misspell` prüft)**. Doku und UI: Deutsch, UI zusätzlich Englisch.
|
||||
- Conventional Commits, kleine Commits, Tag pro Meilenstein erst bei grüner CI. Commit-Trailer: `Co-Authored-By: …`.
|
||||
- Jede Quelldatei trägt einen SPDX-Header passend zum Verzeichnis (`scripts/check-spdx.sh`): proprietär `server/`, `web/`, `tools/`; Apache-2.0 `agent/`, `proto/`, `internal/`, `deploy/`, `scripts/`, `test/`. `depguard` verbietet Importe von `server/`/`web` aus Apache-Code.
|
||||
- OpenAPI (`server/api/openapi.yaml`) ist die Quelle der API. Neue Route = Spezifikation + Routentabelle (`httpapi/routes.go`) + Test; die Vertragstests erzwingen Gleichstand. TypeScript-Typen mit `npm run gen:api` erzeugen und einchecken.
|
||||
- YAML-Flow-Mappings (`{ … }`) mit Kommas im Text: Beschreibung in Anführungszeichen setzen (hat einmal die Spezifikation zerlegt).
|
||||
- Fehler an Nutzer: stabile `code`s, Übersetzungen in `web/src/locales/{de,en}.json` unter `errors.*`/`problems.*`/`effects.*`.
|
||||
- Jede schreibende Service-Operation schreibt ihr Audit in derselben Transaktion; Mehrfachoperationen nutzen `Tx.Nested` (Savepoints), damit ein Fehler die Transaktion nicht abbricht.
|
||||
- `.gitignore` enthält **kein** globales `*.test` (hat einmal die Zone `db.dev.test` verschluckt).
|
||||
|
||||
---
|
||||
|
||||
## Verlauf
|
||||
|
||||
### 2026-10-12 – M1 Server-Kern (`v0.2.0`)
|
||||
|
||||
- Keygen-Instanz geprüft: Edition CE 1.8, Modus singleplayer, Account `9de54794-8e94-4250-83f6-87e3d5686a0b`; Signatur `ed25519` über `(request-target) host date digest` mit dem Account-Schlüssel erfolgreich verifiziert. Account-ID und öffentlicher Schlüssel werden beim Build eingebettet (`Makefile`), nicht per Konfiguration überschreibbar.
|
||||
- Neue ADRs: 0019 (OpenAPI-Vertragstests statt Server-Codegenerierung – `oapi-codegen` war lokal nicht ausführbar), 0020 (Authentifizierung, Sitzungen, Rollen); 0016 um geprüfte Fakten ergänzt.
|
||||
- Umgesetzt: Konfiguration (YAML + Env), Geheimnisverschlüsselung (AES-256-GCM, Schlüssel-IDs), Schema mit Datenbank-Constraints, Argon2id/TOTP/Sitzungen/CSRF/Rate-Limit/RBAC, Audit, IPAM-Fachlogik (effektive Pools, Auslastung, Adresskarte, Änderungsvorschau), Lizenzmodul (Provider, Lizenzdateien, Zustandsautomat, Manager), Service-Schicht, REST-API (46 Operationen) mit Vertragstests, OIDC-Flow mit PKCE, Metriken, CLI-Befehle, Weboberfläche, `tools/keygen-setup`, `docs/LICENSING.md`, `docs/API.md`.
|
||||
- Von Tests gefundene und behobene Fehler: Query-String im Pfad der Keygen-Anfragen; TOTP-Code nach dem Aktivieren erneut verwendbar; Schreibschutz griff erst mit bis zu einer Minute Verzögerung; CSV-Import/Massenänderung hätten nach dem ersten DB-Fehler die Transaktion abgebrochen (jetzt Savepoints); ServeMux-Konflikt `"/api/"` vs. `"GET /"` hätte den Server beim Start abstürzen lassen; Constraint-Fehler ohne spezifischen Code; MAC-Suche mit `-` als Trenner.
|
||||
- Testabdeckung je Paket (CI): auth 83 %, config 84 %, httpapi 81 %, httpserver 94 %, ipam 91 %, license 77 %, secrets 92 %, store 65 %, cmd 68 %.
|
||||
- Entscheidung zur Auslegung des Briefs: Pools sind Bereiche; Gateway, `static`, `reserved`, `manual_dhcp` werden aus dem **effektiven** Pool ausgeschnitten, `dynamic` muss im Pool liegen (ARCHITECTURE §3.2).
|
||||
|
||||
### 2026-10-12 – M0 Fundament (`v0.1.0`)
|
||||
|
||||
- Brief nach `docs/` verschoben, ADRs 0001–0018, ARCHITECTURE, README.
|
||||
- Git-Host als Gitea 1.27.2 erkannt (API-Probe). Kea-Hooks geprüft: `lease_cmds` und `ha` in allen 2.x frei, `host_cmds`/`subnet_cmds` erst ab 3.0 → komplette Konfiguration neu laden statt inkrementell.
|
||||
- Repo-Grundgerüst, Lizenzaufteilung mit SPDX-Prüfung und `depguard`, gRPC-Vertrag `ddi.agent.v1`, Makefile, reproduzierbarer Release-Build, Gitea-Workflows (CI + Release mit Upload), Compose mit PostgreSQL 17 / BIND 9.20 / Kea 3.2.1 und Smoke-Test.
|
||||
- In der CI gefunden und behoben: Hinweisseite der UI lieferte 404; festes Compose-Subnetz kollidierte mit dem Runner-Host; `db.dev.test` durch `*.test` in `.gitignore` nie eingecheckt.
|
||||
- Release `v0.1.0` erfolgreich über den Workflow veröffentlicht, Download-URL-Schema verifiziert.
|
||||
Reference in New Issue
Block a user