diff --git a/.planning/STATE.md b/.planning/STATE.md
index 4bb39b0..ea76b84 100644
--- a/.planning/STATE.md
+++ b/.planning/STATE.md
@@ -31,7 +31,7 @@ See: .planning/PROJECT.md (updated 2026-07-17)
Phase: 18 (desktop-client-fertigstellen) — COMPLETE (2026-09-17, Verifikation passed, Windows-Bedienprobe bestanden)
Plan: 6 of 6
Status: Alle 18 Phasen abgeschlossen; Version 1.2.0 freigegeben. Kein laufender Meilenstein. Nach 1.2.0 auf main (Beta): Bildmarke in Akzentfarbe, CI-Desktop-Skip, Favoriten-Symbol/-Sortierung, Desktop-Server-Adresse, Update in der App (signiert), Versionszeile auf der Setup-Seite — alles verifiziert und auf VM/CI nachgewiesen
-Last activity: 2026-10-08 - Quick 261008-dts Modul Domains (AutoDNS)
+Last activity: 2026-10-08 - Quick 261008-h3t Domains-Nameserver aus AutoDNS
Progress: [██████████] 99%
@@ -498,6 +498,7 @@ Gerettet aus `.continue-here.md`. Relevant fuer die noch offenen Live-Tests.
| 261005-jqd | Einstellungen und Verwaltung aufgeraeumt (gemeinsame Navigation, Seitenkopf, Karten; „Verwaltung“) | 2026-10-05 | 0a35a32 + (dieser Commit) | [261005-jqd-verwaltung-aufgeraeumt](.planning/quick/261005-jqd-verwaltung-aufgeraeumt/) |
| 261006-dcs | Linux-App: weißes Fenster auf Arch/EndeavourOS (libwayland aus AppImage entfernt) | 2026-10-06 | (dieser Commit) | [261006-dcs-linux-app-weisses-fenster-arch](.planning/quick/261006-dcs-linux-app-weisses-fenster-arch/) |
| 261008-dts | Modul Domains: AutoDNS-Anbindung (Zugang Demo/Live, Kunden, Kontakte, Domainliste, Registrieren ohne Doppelbestellung, Aufträge) — Needs Review (Demo-Prüfung offen) | 2026-10-08 | 53b73dd | [261008-dts-modul-domains-autodns-anbindung-kontakte](.planning/quick/261008-dts-modul-domains-autodns-anbindung-kontakte/) |
+| 261008-h3t | Domains: Standard-Nameserver aus AutoDNS-Profil statt Tessera-Einstellung (nur Anzeige, Sperre wenn keine) — Demo-Prüfung offen | 2026-10-08 | 2176f8e | [261008-h3t-domains-nameserver-aus-autodns-statt-tes](.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/) |
## Deferred Items
diff --git a/.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/261008-h3t-PLAN.md b/.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/261008-h3t-PLAN.md
new file mode 100644
index 0000000..d900c94
--- /dev/null
+++ b/.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/261008-h3t-PLAN.md
@@ -0,0 +1,329 @@
+---
+phase: quick-261008-h3t
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+quick_id: 261008-h3t
+description: "Domains: Standard-Nameserver aus dem AutoDNS-Benutzerprofil statt aus einer Tessera-Einstellung"
+date: 2026-10-08
+files_modified:
+ # Task 1 — tracer (API): AutoDNS profile -> parser -> draft payload -> POST /domain body, plus GET name-servers route
+ - apps/api/src/domains/domain-name.ts
+ - apps/api/src/domains/autodns-parse.ts
+ - apps/api/src/domains/autodns-parse.spec.ts
+ - apps/api/src/domains/domains-orders.service.ts
+ - apps/api/src/domains/domains-orders.service.spec.ts
+ - apps/api/src/domains/dto/domains-order.dto.ts
+ - apps/api/src/domains/domains.controller.ts
+ - apps/api/src/domains/domains.controller.spec.ts
+ - apps/api/src/module-registry/module-manage-handlers.spec.ts
+ - apps/api/src/domains/domains-settings.service.ts
+ # Task 2 — web: Registrieren shows AutoDNS nameservers read-only, hint and lock when missing
+ - apps/web/src/lib/domains-api.ts
+ - apps/web/src/app/(portal)/modules/domains/components/RegisterTab.tsx
+ - apps/web/src/app/(portal)/modules/domains/components/RegisterTab.test.tsx
+ - apps/web/src/messages/de.json
+ - apps/web/src/messages/en.json
+ # Task 3 — remove the setting everywhere (DB column, API, web), docs, changelog, rebuild
+ - apps/api/prisma/schema.prisma
+ - apps/api/prisma/migrations/20261008160000_domains_drop_default_nameservers/migration.sql
+ - apps/api/src/domains/domains-settings.service.spec.ts
+ - apps/api/src/domains/domains.types.ts
+ - apps/api/src/domains/dto/domains-settings.dto.ts
+ - apps/api/src/domains/dto/domains-settings.dto.spec.ts
+ - apps/web/src/app/(portal)/modules/domains/components/SettingsTab.tsx
+ - apps/web/src/app/(portal)/modules/domains/domains-page.test.tsx
+ - CHANGELOG.md
+ - docs/anleitung-anwender.md
+ - docs/anleitung-administration.md
+ - docs/mandantentrennung-zugriffsklassifikation.md
+autonomous: true
+requirements: [QUICK-261008-h3t]
+
+estimate:
+ tokens: 100000
+ raw_tokens: 100000
+ tasks: 3
+ confidence: low
+
+must_haves:
+ truths:
+ - "The Einstellungen tab of the module Domains shows no 'Standard-Nameserver' card any more; GET/PUT settings and GET status carry no nameserver field; after the migration the table DomainsConfig has no nameserver column (D-01)"
+ - "A manager opening the Registrieren tab sees the standard nameservers that AutoDNS holds in the profile of the configured AutoDNS user (GET /user/{user}/{context}/profile of the active system), read-only, in AutoDNS order (by the number in the profile key), with no input, add or remove controls (D-02, D-03)"
+ - "Creating a draft ignores any nameservers sent by the browser, reads the AutoDNS profile on the server, stores exactly that ordered list in the draft payload and returns it in the summary; confirming sends exactly that stored list in that order in the one POST /domain; the WR-02 version binding, the atomic DRAFT-to-SUBMITTING claim, the single POST without retry and the UNKNOWN handling are unchanged (D-03)"
+ - "If AutoDNS cannot be read or the profile yields fewer than two recognisable nameservers (or two different values for the same number), the Registrieren tab shows a German Sie-form hint ('In AutoDNS sind keine Standard-Nameserver hinterlegt …' respectively 'Tessera konnte die Standard-Nameserver nicht aus AutoDNS lesen …'), 'Zusammenfassung anzeigen' stays disabled, the server refuses the draft with 409 noDefaultNameServers or the AutoDNS error without writing a row, and submit refuses a draft with fewer than two nameservers before the claim — nothing is guessed (D-04)"
+ - "docs/anleitung-anwender.md, docs/anleitung-administration.md and the existing Domains lines under 'Unveröffentlicht' in CHANGELOG.md describe nameservers coming from AutoDNS; the 261008-dts SUMMARY is unchanged (D-05)"
+ - "The full api and web test suites, both tsc runs and the de/en key parity stay green; the rebuilt stack answers GET modules/domains/name-servers with 200, 409, 502 or 504 (never 404 or 500)"
+ artifacts:
+ - path: "apps/api/src/domains/autodns-parse.ts"
+ provides: "parseProfileNameServers: tolerant recognition of the standard nameservers in an AutoDNS user profile ([ASSUMED] key names)"
+ exports: ["parseProfileNameServers"]
+ - path: "apps/api/src/domains/domains-orders.service.ts"
+ provides: "getProfileNameServers, profile read inside createOrder, pre-claim guard for drafts without nameservers"
+ contains: "noDefaultNameServers"
+ - path: "apps/api/prisma/migrations/20261008160000_domains_drop_default_nameservers/migration.sql"
+ provides: "drops the obsolete settings column"
+ contains: "DROP COLUMN"
+ - path: "apps/web/src/app/(portal)/modules/domains/components/RegisterTab.tsx"
+ provides: "read-only AutoDNS nameserver list, hint with retry, summary locked without nameservers"
+ key_links:
+ - from: "apps/api/src/domains/domains-orders.service.ts createOrder"
+ to: "AutoDNS GET /user/{user}/{context}/profile"
+ via: "readProfileNameServers(credentials) -> payload.nameServers"
+ pattern: "readProfileNameServers\\(credentials\\)"
+ - from: "apps/api/src/domains/domains-orders.service.ts submitOrder"
+ to: "AutoDNS POST /domain"
+ via: "stored payload list in stored order"
+ pattern: "payload\\.nameServers\\.map"
+ - from: "apps/api/src/domains/domains.controller.ts"
+ to: "DomainsOrdersService.getProfileNameServers"
+ via: "GET name-servers with ModuleManage('domains')"
+ pattern: "@Get\\('name-servers'\\)"
+ - from: "apps/web/src/app/(portal)/modules/domains/components/RegisterTab.tsx"
+ to: "GET /modules/domains/name-servers"
+ via: "getNameServers() in apps/web/src/lib/domains-api.ts"
+ pattern: "getNameServers\\("
+---
+
+
+The Tessera setting "Standard-Nameserver" in the module Domains (built in quick 261008-dts, commits 1f1c984..53b73dd) is wrong and goes away. AutoDNS already holds the standard nameservers in the profile of the AutoDNS user (for this user: ns2.ctl.de, b.ns14.net, c.ns14.net, d.ns14.net in exactly that order). Tessera reads them from AutoDNS when a registration is prepared, shows them for control only, stores them with the draft the user confirms and sends them explicitly, in AutoDNS order, in the single POST /domain. Company-specific values are never hard-coded in Tessera — not in code, tests, defaults or docs.
+
+Locked requirements from the request (cited below as D-xx; numbering follows the request):
+- D-01 Remove the settings card "Standard-Nameserver" (web SettingsTab, API DTO/service, validation). DB column: removed by migration (chosen in Task 3; values are worthless).
+- D-02 On registration, read the standard nameservers from the AutoDNS user profile (GET /user/{name}/{context}/profile, response UserProfileViews with profiles[] of key/value). The key names are UNKNOWN: recognise tolerantly (keys containing "ns" plus a number, sorted by that number), encapsulated in one function with tests, assumption documented as [ASSUMED] and put on the demo checklist.
+- D-03 Registrieren tab and summary show the AutoDNS nameservers read-only, in AutoDNS order. They are stored with the draft (part of what the user confirms; WR-02 version binding stays intact) and sent explicitly in that order in POST /domain.
+- D-04 If Tessera cannot read nameservers from AutoDNS (error or no matching keys): clear German Sie-form hint starting "In AutoDNS sind keine Standard-Nameserver hinterlegt …" and registration locked — nothing guessed.
+- D-05 Update docs/anleitung-anwender.md, docs/anleitung-administration.md and the existing Domains lines under "Unveröffentlicht" in CHANGELOG.md (adapt, no new line). Do NOT change the 261008-dts SUMMARY.
+- Money safety (atomic claim, exactly one POST, UNKNOWN) is not touched except where needed; all existing tests stay green.
+
+Discretion choices (documented here, cited in tasks):
+- On a read ERROR (auth, timeout, gateway) the hint says "Tessera konnte die Standard-Nameserver nicht aus AutoDNS lesen …" plus the AutoDNS detail, because "no nameservers stored" would be false in that case; both cases lock registration identically. The "no matching keys" case uses the requested opening sentence verbatim.
+- The server reads the profile itself inside createOrder (authoritative); the browser list is informational. The client never sends nameservers.
+- Fewer than two recognised nameservers counts as "not stored" (.de needs at least two). No upper cap and no truncation (truncating would be guessing); AutoDNS validates the rest.
+
+Purpose: AutoDNS stays the single source of the nameserver defaults; Tessera holds no company-specific values and never registers with nameservers the user did not see.
+Output: profile parser with tests, API route GET name-servers, draft/summary/submit using the AutoDNS list, read-only Registrieren display with lock, setting removed including DB column, docs and changelog updated.
+
+
+
+@~/.claude/gsd-core/workflows/execute-plan.md
+@~/.claude/gsd-core/templates/summary.md
+
+
+
+@.planning/STATE.md
+@./CLAUDE.md
+@.planning/quick/261008-dts-modul-domains-autodns-anbindung-kontakte/261008-dts-SUMMARY.md
+@.planning/quick/261008-dts-modul-domains-autodns-anbindung-kontakte/261008-dts-REVIEW.md
+
+Project rules that apply here:
+- NestJS: static routes before any `:id` route (domains.controller.spec.ts checks declaration order).
+- API TS lib has no Object.hasOwn; use `Object.prototype.hasOwnProperty.call` or `in`.
+- Never read .env files. Rebuild locally with `docker compose up -d --build api web` (the api container runs `prisma migrate deploy` on start). No deploy to the test server, no push (commits stay local; the user pushes bundled).
+- UI texts: Sie-form, real umlauts (apps/web/src/messages/umlaut-guard.spec.ts fails on ae/oe/ue substitutes), de/en keys identical, no "Mandant"/"Lizenz".
+- Global ValidationPipe: `whitelist: true`, no forbidNonWhitelisted — unknown body fields are stripped, not rejected.
+
+AutoDNS spec facts (Swagger 2.0, already checked by the planner; the local copy is a session scratch file the executor need not open):
+- GET /user/{name}/{context}/profile (operationId userProfileInfo, task 1301017) -> JsonResponseDataUserProfileViews: `data` is an array of UserProfileViews `{ profiles: UserProfileView[] }`; UserProfileView has `key` (string, example "techc"), `value` (string), `flag`, `inherited` (bool), `readonly` (bool), created/updated/owner/updater.
+- Domain has `nameServers[]` (objects with `name`), `nameServerGroup`, `zone`. The existing POST /domain body already sends `nameServers: [{ name }]`.
+- Base URLs (autodns-client.ts AUTODNS_BASE_URLS): Demo `https://api.demo.autodns.com/v1`, Live `https://api.autodns.com/v1`. `autodnsRequest` rejects paths containing `..`, `?`, `#`, `//` or whitespace by throwing.
+
+
+
+
+
+ Task 1 (tracer): AutoDNS profile -> parser -> draft payload -> POST /domain body, plus GET name-servers
+ apps/api/src/domains/domain-name.ts, apps/api/src/domains/autodns-parse.ts, apps/api/src/domains/autodns-parse.spec.ts, apps/api/src/domains/domains-orders.service.ts, apps/api/src/domains/domains-orders.service.spec.ts, apps/api/src/domains/dto/domains-order.dto.ts, apps/api/src/domains/domains.controller.ts, apps/api/src/domains/domains.controller.spec.ts, apps/api/src/module-registry/module-manage-handlers.spec.ts, apps/api/src/domains/domains-settings.service.ts
+ apps/api/src/domains/autodns-parse.ts, apps/api/src/domains/domains-orders.service.ts (lines 1-600: ERR, readPayload, callRaw, createOrder, submitOrder), apps/api/src/domains/domains-orders.service.spec.ts (harness lines 1-160, createOrder block around line 333, submit block around line 480-560), apps/api/src/domains/domains.controller.ts, apps/api/src/domains/domains.controller.spec.ts (lines 1-60 and 95-140), apps/api/src/module-registry/module-manage-handlers.spec.ts (lines 85-105), apps/api/src/domains/domain-name.ts
+
+ - parseProfileNameServers, UserProfileViews shape: entries ns3/ns1/ns4/ns2 listed out of order (plus a techc entry) -> hostnames ordered ns1, ns2, ns3, ns4; techc ignored (D-02)
+ - numeric sort: ns10 comes after ns9, not after ns1
+ - value normalisation: " Z.Example.NET. " -> "z.example.net"; values that are no hostname (IP 192.0.2.1, empty, "kein rechner", "a.example.org 192.0.2.1") are skipped
+ - key variants recognised: nameserver1, NS_2, default_ns3, nserver4 (case-insensitive)
+ - flat items `{ key, value }` directly in data are accepted as well as `{ profiles: [...] }` and a single object with profiles
+ - same number with two different hostnames -> empty list (ambiguous, nothing guessed); same number with the same hostname -> once; the same hostname under two numbers -> first kept
+ - list fallback, only when no numbered key yields a hostname: key "nameservers" with "a.example.org, b.example.org" -> that order; two list keys with different lists -> empty
+ - garbage input (null, "x", {}, [1, 2]) -> `{ nameServers: [], keys: [] }`; `keys` lists the profile keys seen (for the log line)
+ - getProfileNameServers: exactly one GET to `https://api.demo.autodns.com/v1/user/api-user/4/profile`; returns `{ environment: 'DEMO', nameServers }` in key order; a user name with a space is percent-encoded in the path
+ - profile without nameserver keys -> 409 code noDefaultNameServers; AutoDNS 401 -> 502 autodnsAuth; timeout -> 504 (D-04)
+ - createOrder: payload.nameServers and summary.nameServers equal the profile order (neither alphabetical nor from the request); a request body with nameServers ['evil.example.com', 'x.example.com'] is ignored (D-03)
+ - createOrder with a profile without nameservers -> 409 noDefaultNameServers, no row written, no /domainstudio call; profile answered 500 -> rejected, no row (D-04)
+ - createOrder on an existing DRAFT re-reads the profile and returns a new version (WR-02 binding intact)
+ - tracer chain (describe 'Nameserver aus AutoDNS (h3t)'): createOrder -> submitOrder(id, version) -> exactly one POST /domain whose body.nameServers is [{ name }] in profile order
+ - submit guard: a DRAFT whose payload.nameServers is [] or has one entry -> 400 orderInvalid, the claim updateMany is not called, zero AutoDNS calls
+ - every existing submit, claim, UNKNOWN, reconcile and cancel test passes unchanged
+ - controller: getNameServers is GET 'name-servers', carries ModuleManage('domains'), no role decorator, is declared before every :id handler and forwards req.tenantId
+
+
+Write the tests from the behavior list first (RED), then implement (GREEN). This task proves the money path end-to-end inside the API; the web follows in Task 2, the removal of the old setting in Task 3.
+
+1. domain-name.ts: move the hostname regex constant HOSTNAME_PATTERN here unchanged and export it. In domains-settings.service.ts delete its local definition and import it from './domain-name' (its own nameserver normaliser stays until Task 3). In domains-orders.service.ts import it from './domain-name' instead of the settings service. autodns-parse.ts imports it from './domain-name' too (no dependency from the parser on a Nest service).
+
+2. autodns-parse.ts (D-02): add exported parseProfileNameServers(data: unknown) returning `{ nameServers: string[]; keys: string[] }`. Doc comment in German stating: the key names of the standard nameservers in the AutoDNS user profile are not documented — [ASSUMED], recognised tolerantly, checked by H-1 on the demo checklist of quick 261008-h3t. Rules:
+ a. Collect entries: data may be an array of `{ profiles: [...] }` (spec), an array of flat `{ key, value }` items, or one object with `profiles`. Keep items whose key and value are strings. `keys` = distinct trimmed keys in first-seen order, at most 50, each cut to 60 characters.
+ b. Normalise a value: trim, lowercase, remove one trailing dot; accept it only if the whole result matches HOSTNAME_PATTERN (no token splitting for numbered keys).
+ c. Numbered keys: lowercase the key and search anywhere in it for the regex `(?:nameserver|name[_-]server|nserver|ns)[_.-]?(\d{1,2})(?!\d)`; the captured number is the position. Skip entries whose value is not a hostname (for example glue addresses).
+ d. If one position carries two different hostnames, return an empty list (never pick one). The same hostname twice at one position counts once.
+ e. Sort by position numerically, then drop repeated hostnames keeping the first occurrence.
+ f. Only if step c produced no hostname: keys matching exactly `^(?:default[_.-]?)?(?:nameservers?|name[_-]servers?|nservers?|ns)$` whose value split on `[\s,;]+` gives tokens that are ALL hostnames provide that list in written order; two such keys with different lists give an empty list.
+ g. No minimum here; the caller enforces it.
+
+3. domains-orders.service.ts:
+ - Add ERR.noDefaultNameServers with code 'noDefaultNameServers' and message "In AutoDNS sind keine Standard-Nameserver hinterlegt. Bitte hinterlegen Sie mindestens zwei Nameserver als Standard in AutoDNS; bis dahin ist keine Registrierung möglich." (thrown as ConflictException, D-04).
+ - Private readProfileNameServers(credentials): exactly one callRaw GET to the path `/user/` + encodeURIComponent(credentials.user) + `/` + credentials.context + `/profile` — no query, no retry. A thrown error (for example the client's path check) becomes BadGatewayException with code 'autodnsError' and message "Tessera konnte die Standard-Nameserver nicht aus AutoDNS lesen."; a result with ok false is thrown via autodnsFailureToHttp. Parse with parseProfileNameServers; with fewer than MIN_NAMESERVERS (2) entries log one warning via this.logger.warn that starts with "Keine Standard-Nameserver im AutoDNS-Profil erkannt" and lists only the profile key names (never values, never credentials), then throw ERR.noDefaultNameServers. Otherwise return the list.
+ - Public getProfileNameServers(tenantId): getActiveCredentials (409 notConfigured unchanged), then readProfileNameServers; returns `{ environment, nameServers }`.
+ - createOrder (D-03): delete the use of the request's nameservers and the method normalizeNameServers plus MAX_NAMESERVERS (no other user). Directly after the existing-order check and before availabilityFor, call readProfileNameServers(credentials) and put the returned ordered list into payload.nameServers. Everything else (availability, contact check, write, summary with version) stays as is; the summary keeps returning payload.nameServers.
+ - submitOrder: the only change is the existing pre-claim guard — "payload missing" becomes "payload missing OR payload.nameServers.length below MIN_NAMESERVERS", same 400 orderInvalid. Do not touch the claim, the single POST, the body mapping (order preserved, never sorted), outcomeOfSubmit, recoverFailedOutcomeWrite, reconcile or cancelOrder.
+ - Adjust doc comments that mention nameservers coming from the settings or the browser.
+
+4. dto/domains-order.dto.ts: remove the nameServers field from CreateDomainsOrderDto and the class-validator imports that become unused; doc comment: the nameservers come from AutoDNS, never from the browser. A browser still sending the field is stripped by the whitelist ValidationPipe.
+
+5. domains.controller.ts: add handler getNameServers with `@Get('name-servers')` and `@ModuleManage('domains')`, calling this.orders.getProfileNameServers(this.requireTenantId(req)). Place it directly after checkAvailability in the static section (before every `:id` route). No role decorator. Add "Standard-Nameserver aus AutoDNS lesen" to the Verwalten list in the class doc comment.
+
+6. Tests:
+ - autodns-parse.spec.ts: the parser cases from the behavior list, example hostnames only (example.org, example.net, example.com).
+ - domains-orders.service.spec.ts: extend makeHarness so GET calls whose URL ends with '/profile' are answered by a separate, overridable profile responder (default: envelope with one `{ profiles: [...] }` item listing ns3, ns1, ns4, ns2 out of order with example hostnames whose alphabetical order differs from the key order, plus a techc entry); these calls are still recorded in h.calls. Remove nameServers from the createOrder dto fixture and delete the "Nameserver %j -> BadRequest %s" table test (its rules are gone with D-02). Add the service, createOrder, tracer-chain and submit-guard tests from the behavior list. If an existing test counts all calls of a createOrder run, account for the one profile call explicitly rather than weakening the assertion.
+ - domains.controller.spec.ts: add 'getNameServers' to MANAGE_HANDLERS, `getProfileNameServers` to makeOrders, the route expectation `[0, 'name-servers']`, and a forwarding test.
+ - module-manage-handlers.spec.ts: add 'getNameServers' to the DomainsController list only; do not reformat the file (its organizeImports finding is pre-existing).
+
+Commit: `feat(domains): Standard-Nameserver aus dem AutoDNS-Profil lesen (h3t)`.
+
+
+ pnpm --filter @tessera/api exec vitest run src/domains module-manage-handlers rls-coverage rls-access-inventory && pnpm --filter @tessera/api exec tsc --noEmit && test -z "$(grep -nE '^\s*@Roles\(' apps/api/src/domains/domains.controller.ts)" && grep -q "@Get('name-servers')" apps/api/src/domains/domains.controller.ts && grep -q "Nameserver aus AutoDNS (h3t)" apps/api/src/domains/domains-orders.service.spec.ts && echo "tracer api ok"
+
+ Profile parser covered by tests; createOrder stores the AutoDNS list in AutoDNS order and the chained test proves the one POST /domain carries it unchanged; missing or unreadable profile nameservers block the draft with 409/502/504 and no row; drafts without two nameservers never reach the claim; GET name-servers is a Verwalten route before all :id routes; every existing domains test is green.
+
+
+
+ Task 2: Registrieren shows the AutoDNS nameservers read-only, with hint and lock when missing
+ apps/web/src/lib/domains-api.ts, apps/web/src/app/(portal)/modules/domains/components/RegisterTab.tsx, apps/web/src/app/(portal)/modules/domains/components/RegisterTab.test.tsx, apps/web/src/messages/de.json, apps/web/src/messages/en.json
+ apps/web/src/app/(portal)/modules/domains/components/RegisterTab.tsx, apps/web/src/app/(portal)/modules/domains/components/RegisterTab.test.tsx, apps/web/src/lib/domains-api.ts (lines 1-80 and 280-360), apps/web/src/messages/de.json and en.json (block domains.register)
+
+ - With getNameServers resolving ['z.example.net', 'b.example.org', 'a.example.org'], the nameserver section lists exactly these in this DOM order, read-only: no textbox labelled 'Nameserver 1', no button 'Nameserver hinzufügen' (D-03)
+ - getNameServers rejecting with DomainsRequestError(409, 'noDefaultNameServers', …) shows an alert containing "In AutoDNS sind keine Standard-Nameserver hinterlegt"; after a free domain and chosen contacts, "Zusammenfassung anzeigen" is disabled and createOrder is never called (D-04)
+ - getNameServers rejecting with DomainsRequestError(502, 'autodnsAuth', 'Anmeldung bei AutoDNS fehlgeschlagen …') shows "Tessera konnte die Standard-Nameserver nicht aus AutoDNS lesen" plus the server text; "Erneut aus AutoDNS lesen" calls getNameServers again, and after success the list appears and the summary button becomes enabled
+ - createOrder is called with exactly { domain, ownerContactId, adminContactId, techContactId, zoneContactId } — no nameServers key (D-03)
+ - the summary shows the server's list in its order: "z.example.net, b.example.org, a.example.org"
+ - existing tests for double-click lock, submit error lock, orderChanged and cancel stay green
+
+
+1. domains-api.ts: add interface DomainsNameServers `{ environment: DomainsEnvironment; nameServers: string[] }` and function getNameServers() that requests '/name-servers' (GET, same request helper as listOrders). Remove nameServers from CreateOrderInput (D-03: the server reads them itself). Leave the DomainsStatus and DomainsSettings types alone — Task 3 removes their old field.
+
+2. RegisterTab.tsx (D-03, D-04):
+ - Remove the editable nameserver list completely: the MIN/MAX constants used only for it, initialNameServers, the nameServers state seeded from the status prop, the inputs and the add/remove buttons. resetAll no longer touches nameservers.
+ - New state for the AutoDNS list, a small union: loading, ok with list, missing, unreadable with detail. Load via getNameServers on mount and whenever status.environment changes, guarded by an alive flag like the contacts effect. DomainsRequestError with code 'noDefaultNameServers' -> missing; any other error -> unreadable with detail = the DomainsRequestError message, else tc('requestFailed').
+ - When missing or unreadable, render one hint with role="alert" at the top of the input view (above the domain section, so it is visible before anything is filled in): t('nameServersMissing') or t('nameServersUnreadable') followed by the detail line, plus a SECONDARY_BUTTON t('nameServersRetry') that reloads. The availability check stays usable.
+ - The nameserver section keeps its place (shown once the domain is free) and keeps the "Zusammenfassung anzeigen" footer; description t('nameServersDescription'); content: loading -> t('nameServersLoading'); ok -> an ordered list (ol) whose items show t('nameServer', { number }) and the hostname as plain text, nothing editable; missing or unreadable -> t('nameServersBlocked').
+ - canSummarize additionally requires the ok state with at least two entries.
+ - onSummary calls createOrder without nameservers.
+ - The summary row keeps summary.nameServers joined with ", " (server order = AutoDNS order). Update the component doc comment (nameservers come from AutoDNS, read-only).
+
+3. de.json / en.json, block domains.register (identical keys in both; Sie-form; real umlauts):
+ - intro: "Prüfen Sie, ob eine Domain frei ist, wählen Sie die Kontakte und registrieren Sie die Domain verbindlich bei AutoDNS. Die Nameserver übernimmt Tessera aus AutoDNS."
+ - nameServersDescription: "Diese Standard-Nameserver sind in AutoDNS hinterlegt. Tessera verwendet sie unverändert und in dieser Reihenfolge; ändern lassen sie sich nur in AutoDNS."
+ - keep nameServer ("Nameserver {number}"); delete addNameServer and removeNameServer
+ - add nameServersLoading: "Nameserver werden aus AutoDNS gelesen …"
+ - add nameServersMissing: "In AutoDNS sind keine Standard-Nameserver hinterlegt. Bitte hinterlegen Sie mindestens zwei Nameserver als Standard in AutoDNS. Bis dahin ist keine Registrierung möglich."
+ - add nameServersUnreadable: "Tessera konnte die Standard-Nameserver nicht aus AutoDNS lesen. Bis das gelingt, ist keine Registrierung möglich." (discretion choice, see objective)
+ - add nameServersRetry: "Erneut aus AutoDNS lesen"
+ - add nameServersBlocked: "Ohne Standard-Nameserver aus AutoDNS ist keine Registrierung möglich – siehe Hinweis oben."
+ - English counterparts with the same meaning. Do not touch domains.settings.nameServers yet (Task 3).
+
+4. RegisterTab.test.tsx: add a mockNameServers for getNameServers in the existing vi.mock (default resolves the example list from the behavior block); replace the prefill assertion and the "zwischen 2 und 6" test with the behavior cases; keep the status fixture as it is (Task 3 drops its old field).
+
+Commit: `feat(domains): Registrieren zeigt Nameserver aus AutoDNS nur zur Kontrolle (h3t)`.
+
+
+ pnpm --filter @tessera/web exec vitest run modules/domains src/messages && pnpm --filter @tessera/web exec tsc --noEmit && node -e 'const de=require("./apps/web/src/messages/de.json"),en=require("./apps/web/src/messages/en.json");const w=(o,p,r)=>{for(const[k,v]of Object.entries(o||{})){const q=p+"."+k;if(v&&typeof v==="object")w(v,q,r);else r[q]=v}return r};const a=w(de.domains,"domains",{}),b=w(en.domains,"domains",{});if(Object.keys(a).length<40||Object.keys(a).sort().join()!==Object.keys(b).sort().join()){console.error("key mismatch");process.exit(1)}if(!String(a["domains.register.nameServersMissing"]).startsWith("In AutoDNS sind keine Standard-Nameserver hinterlegt")){console.error("hint text");process.exit(1)}for(const v of [...Object.values(a),...Object.values(b)])if(/mandant|tenant|lizenz|licens/i.test(String(v))){console.error("bad text",v);process.exit(1)}console.log("web register ok")'
+
+ The Registrieren tab lists the AutoDNS nameservers read-only in AutoDNS order, shows the German hint with a retry button when they are missing or unreadable, keeps "Zusammenfassung anzeigen" disabled in that case, and no longer sends nameservers when creating a draft; de/en keys match; web domains tests and the umlaut guard are green.
+
+
+
+ Task 3: Remove the setting everywhere (DB column, API, web), update docs and changelog, rebuild
+ apps/api/prisma/schema.prisma, apps/api/prisma/migrations/20261008160000_domains_drop_default_nameservers/migration.sql, apps/api/src/domains/domains-settings.service.ts, apps/api/src/domains/domains-settings.service.spec.ts, apps/api/src/domains/domains.types.ts, apps/api/src/domains/dto/domains-settings.dto.ts, apps/api/src/domains/dto/domains-settings.dto.spec.ts, apps/web/src/lib/domains-api.ts, apps/web/src/app/(portal)/modules/domains/components/SettingsTab.tsx, apps/web/src/app/(portal)/modules/domains/domains-page.test.tsx, apps/web/src/app/(portal)/modules/domains/components/RegisterTab.test.tsx, apps/web/src/messages/de.json, apps/web/src/messages/en.json, CHANGELOG.md, docs/anleitung-anwender.md, docs/anleitung-administration.md, docs/mandantentrennung-zugriffsklassifikation.md
+ apps/api/src/domains/domains-settings.service.ts, apps/api/src/domains/domains-settings.service.spec.ts, apps/api/src/domains/dto/domains-settings.dto.ts, apps/api/src/domains/dto/domains-settings.dto.spec.ts, apps/web/src/app/(portal)/modules/domains/components/SettingsTab.tsx (lines 1-40 and 340-509), apps/web/src/app/(portal)/modules/domains/domains-page.test.tsx (fixtures near lines 70-90, nameserver test near line 357), CHANGELOG.md lines 1-15, docs/anleitung-administration.md lines 362-372, docs/anleitung-anwender.md lines 174-180, docs/mandantentrennung-zugriffsklassifikation.md line 901
+ The local stack is up: `docker compose ps --status running --services` lists db (the rebuild below needs it).
+ Dropping the column discards the stored values (the user confirmed they are worthless); bringing it back would need a new migration.
+
+
+1. Database (D-01): remove the field defaultNameServers from model DomainsConfig in schema.prisma. Create apps/api/prisma/migrations/20261008160000_domains_drop_default_nameservers/migration.sql with a short German header comment (quick-261008-h3t: die Standard-Nameserver kommen aus dem AutoDNS-Benutzerprofil; die Spalte wird nicht mehr gelesen, ihre Werte sind wertlos) and the single statement ALTER TABLE "DomainsConfig" DROP COLUMN "defaultNameServers"; — removal chosen over leaving the column unused because the module is unreleased, nothing reads the column after this task, and a dead column would mislead later work. No RLS change (no new table). Run `pnpm --filter @tessera/api exec prisma generate`.
+
+2. API (D-01):
+ - domains-settings.service.ts: remove the nameserver constants, the HOSTNAME_PATTERN import, the field from ConfigRow, normalizeNameServers, the saveSettings branch, getDefaultNameServers (no caller since Task 1) and the field in toSettingsView and getStatus; update the class doc comment (no Standard-Nameserver any more). Keep the remaining two forTenant raw hits (loadRow, saveSettings) unchanged so the access inventory stays correct.
+ - domains.types.ts: remove the field from DomainsSettingsView and DomainsStatusView.
+ - dto/domains-settings.dto.ts: remove the field and the class-validator imports that become unused.
+ - Specs: domains-settings.service.spec.ts drops the fixture fields and the nameserver test and adjusts view expectations; add one assertion that getSettings and getStatus return objects without any nameserver property. dto spec: remove the field from the valid body and from the null list.
+
+3. Web (D-01):
+ - domains-api.ts: remove the field from DomainsStatus, DomainsSettings and SaveDomainsSettingsInput.
+ - SettingsTab.tsx: delete NameServersCard, padNameServers, the row constants, its render line and imports that become unused.
+ - de.json and en.json: delete the block domains.settings.nameServers in both.
+ - domains-page.test.tsx: drop the fixture fields and the test "Nameserver: speichert die bereinigte Liste"; add a test that the Einstellungen tab renders no "Standard-Nameserver" heading and no element with id domains-nameservers.
+ - RegisterTab.test.tsx: drop the old field from the status fixture.
+
+4. Docs and changelog (D-05; Sie-form in user docs as before; never name the user's concrete nameserver hostnames anywhere):
+ - docs/anleitung-administration.md, section "Domains: AutoDNS anbinden": replace the bullet "Standard-Nameserver" with a bullet "Nameserver kommen aus AutoDNS": Tessera has no own nameserver setting; for every registration it reads the standard nameservers from the AutoDNS user profile of the AutoDNS user entered in the settings (also values inherited from a parent user) and uses them unchanged, in the order stored there; store at least two there; they must be set up, because for .de domains the DENIC checks them at registration; if Tessera finds none or cannot read them, the Registrieren tab shows a hint and registration is not possible. In the bullet "Eigener AutoDNS-Benutzer" add that the user must be able to read its own user profile.
+ - docs/anleitung-anwender.md, "Eine Domain registrieren" step 2: replace the sentence about prefilled nameservers ("zwei bis sechs") with: below the contacts you see, for control only, the nameservers stored as standard in AutoDNS, in the order stored there; they can only be changed in AutoDNS; if none are stored, a hint appears and registration is locked. Step 3 (summary lists Nameserver) stays.
+ - CHANGELOG.md under "Unveröffentlicht", adapt the existing Domains lines, no new line: in the line "Domains, Anbindung an AutoDNS" delete the closing sentence about Standard-Nameserver being prefilled; in the line "Domains, Registrieren" replace "Kontakte und Nameserver wählen" with "Kontakte wählen; die Nameserver übernimmt Tessera unverändert und in derselben Reihenfolge aus den Standardwerten in AutoDNS (sind dort keine hinterlegt, ist die Registrierung gesperrt)".
+ - docs/mandantentrennung-zugriffsklassifikation.md line 901 (row domains-settings.service.ts): remove ", Standard-Nameserver" from the description and append "Spalte für Standard-Nameserver mit quick-261008-h3t entfernt (Migration 20261008160000)." Keep the table columns unchanged.
+ - Do not edit .planning/quick/261008-dts-*/261008-dts-SUMMARY.md.
+
+5. Run `pnpm exec biome check` on the touched source directories apps/api/src/domains and "apps/web/src/app/(portal)/modules/domains" plus apps/web/src/lib/domains-api.ts (not on module-manage-handlers.spec.ts, whose finding is pre-existing) and fix what it reports.
+
+6. Rebuild locally: `docker compose up -d --build api web`; wait until the api answers on http://localhost:3001 and its log shows the migrations applied without error. Nothing is pushed and nothing is deployed to the test server.
+
+Commit: `refactor(domains): Einstellung Standard-Nameserver entfernt, Doku angepasst (h3t)`.
+
+
+ pnpm --filter @tessera/api test && pnpm --filter @tessera/web test && pnpm --filter @tessera/api exec tsc --noEmit && pnpm --filter @tessera/web exec tsc --noEmit && ! grep -rn defaultNameServers apps/api/src apps/web/src && ! grep -rnE "ns14|ns2\.ctl" apps/api/src apps/web/src docs CHANGELOG.md && grep -q 'DROP COLUMN "defaultNameServers"' apps/api/prisma/migrations/20261008160000_domains_drop_default_nameservers/migration.sql && grep -q "Nameserver kommen aus AutoDNS" docs/anleitung-administration.md && grep -q "Standardwerten in AutoDNS" CHANGELOG.md && node -e 'const de=require("./apps/web/src/messages/de.json"),en=require("./apps/web/src/messages/en.json");const w=(o,p,r)=>{for(const[k,v]of Object.entries(o||{})){const q=p+"."+k;if(v&&typeof v==="object")w(v,q,r);else r[q]=v}return r};const a=w(de.domains,"domains",{}),b=w(en.domains,"domains",{});if(Object.keys(a).sort().join()!==Object.keys(b).sort().join()||Object.keys(a).some(k=>k.startsWith("domains.settings.nameServers"))){console.error("keys");process.exit(1)}' && docker compose ps --status running --services | grep -qx api && docker compose ps --status running --services | grep -qx web && test "$(docker compose exec -T db psql -U tessera -d tessera -tAc "SELECT count(*) FROM information_schema.columns WHERE table_name='DomainsConfig' AND column_name='defaultNameServers'")" = "0" && A=$(mktemp) && curl -sf -c "$A" -H 'Content-Type: application/json' -d '{"username":"admin","password":"admin123"}' http://localhost:3001/auth/login >/dev/null && MID=$(curl -sf -b "$A" http://localhost:3001/modules/catalog | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const m=JSON.parse(s).find(x=>x.slug==="domains");if(!m)process.exit(1);process.stdout.write(m.isActiveForTenant?"":m.id)})') && { [ -z "$MID" ] || curl -sf -b "$A" -X POST "http://localhost:3001/modules/$MID/activate" >/dev/null; } && S=$(curl -sf -b "$A" http://localhost:3001/modules/domains/settings) && echo "$S" | grep -q '"hasPassword"' && ! echo "$S" | grep -q defaultNameServers && C=$(curl -s -o /dev/null -w '%{http_code}' -b "$A" http://localhost:3001/modules/domains/name-servers) && case "$C" in 200|409|502|504) echo "final gates ok (name-servers $C)";; *) echo "name-servers answered $C"; exit 1;; esac
+ End of task, with Demo credentials entered by the user (record as checklist H-1..H-4 in the SUMMARY; not run by the executor): H-1 [ASSUMED] key names — Registrieren tab lists the Demo user's standard nameservers in the AutoDNS order; if instead the hint "In AutoDNS sind keine Standard-Nameserver hinterlegt" appears although AutoDNS has values, read the warning line "Keine Standard-Nameserver im AutoDNS-Profil erkannt" in `docker compose logs api` (it lists the key names) and adapt parseProfileNameServers. H-2 the AutoDNS user may read its own profile (no 403; a 403 shows the unreadable hint). H-3 a demo registration sends the shown nameservers and AutoDNS accepts them explicitly. H-4 Live: the list matches the four values the user named, in that order. H-x replaces item 8 (A8) of the 261008-dts demo checklist, whose step "Standard-Nameserver in den Einstellungen eintragen" no longer exists.
+
+ No "Standard-Nameserver" card in Einstellungen, no nameserver field in settings/status API and web types, column dropped by migration 20261008160000 and absent in the local DB; docs and the existing CHANGELOG Domains lines describe nameservers from AutoDNS; full api and web suites, both tsc runs and biome on touched files are green; the rebuilt stack serves GET name-servers without 404/500.
+
+
+
+
+
+## Trust Boundaries
+
+| Boundary | Description |
+|----------|-------------|
+| browser -> API | Manager-controlled request bodies for draft creation and submit; the nameserver list must not be taken from here |
+| API -> AutoDNS | Profile read (new GET) and the existing single POST /domain; AutoDNS answers are untrusted input to the parser |
+| API -> logs | New warning line when no nameservers are recognised |
+
+## STRIDE Threat Register
+
+| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
+|-----------|----------|-----------|----------|-------------|-----------------|
+| T-h3t-01 | Tampering | createOrder request body | high | mitigate | Field removed from CreateDomainsOrderDto (whitelist strips it); server reads the profile itself; test proves a sent list is ignored (Task 1) |
+| T-h3t-02 | Tampering | draft vs. confirmed order | high | mitigate | List stored in the draft payload; summary returns it; WR-02 `updatedAt` binding in the claim unchanged; re-creating a draft re-reads the profile and changes the version (Task 1 test) |
+| T-h3t-03 | Tampering | profile path built from the stored AutoDNS user name | medium | mitigate | `encodeURIComponent` on the user name plus the client's existing path check; a thrown path error becomes 502 autodnsError, never a request to another path (Task 1) |
+| T-h3t-04 | Repudiation / integrity | guessing nameservers | high | mitigate | Ambiguous or fewer than two recognised values -> 409 noDefaultNameServers, no draft; submit guard rejects drafts with fewer than two nameservers before the claim; web keeps the summary button disabled (Tasks 1, 2) |
+| T-h3t-05 | Information Disclosure | warning log line | low | mitigate | Logs only profile key names (max 50, 60 chars each), never values or credentials (Task 1) |
+| T-h3t-06 | Denial of Service | extra AutoDNS calls | low | accept | One profile GET per Registrieren load and per draft, Verwalten only, through the shared 350 ms limiter, no retry |
+| T-h3t-07 | Elevation of Privilege | GET name-servers | medium | mitigate | `@ModuleManage('domains')`, no role decorator, class-level `@UseModule`; controller spec and module-manage-handlers spec assert it (Task 1) |
+| T-h3t-08 | Tampering | money-safety path | critical | mitigate | Claim, single POST, outcome mapping, UNKNOWN recovery, reconcile and cancel untouched; all existing submit/claim/reconcile tests must pass unchanged (Task 1 verify, Task 3 full suite) |
+| T-h3t-SC | Tampering | npm/pip/cargo installs | high | accept | No package installs in this plan; nothing to audit |
+
+
+
+- Task 1: api domains specs, module-manage-handlers, rls-coverage, rls-access-inventory and api tsc green; tracer chain test present; no role decorator in the controller.
+- Task 2: web domains tests and message guards green, web tsc green, de/en key parity, hint text starts with the requested sentence.
+- Task 3: full api and web suites, both tsc runs, biome on touched files, no old field in apps/*/src, no company-specific nameserver hostnames in code, docs or changelog, migration present and applied (column absent in the local DB), rebuilt api/web running, GET name-servers answers 200/409/502/504.
+
+
+
+- The setting "Standard-Nameserver" is gone from UI, API, DTOs, types and database (D-01).
+- Registration uses only the nameservers AutoDNS holds in the user profile, recognised by one tested function with the [ASSUMED] key rule (D-02).
+- Registrieren and the summary show them read-only in AutoDNS order; the draft stores them, the one POST /domain sends them in that order, WR-02 still binds the confirmation (D-03).
+- Without readable nameservers, a clear German hint appears and registration is locked in browser and server (D-04).
+- Docs and the existing CHANGELOG Domains lines updated; 261008-dts SUMMARY untouched (D-05).
+- Money safety unchanged; every pre-existing test still green.
+
+
+
diff --git a/.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/261008-h3t-SUMMARY.md b/.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/261008-h3t-SUMMARY.md
new file mode 100644
index 0000000..7011610
--- /dev/null
+++ b/.planning/quick/261008-h3t-domains-nameserver-aus-autodns-statt-tes/261008-h3t-SUMMARY.md
@@ -0,0 +1,96 @@
+---
+phase: quick-261008-h3t
+plan: 01
+subsystem: domains
+tags: [autodns, nameserver, domains, migration]
+requires:
+ - quick-261008-dts (Modul Domains)
+provides:
+ - Standard-Nameserver kommen aus dem AutoDNS-Benutzerprofil (GET /user/{user}/{context}/profile)
+ - GET modules/domains/name-servers (Verwalten)
+affects:
+ - apps/api/src/domains
+ - apps/web Registrieren und Einstellungen
+tech-stack:
+ added: []
+ patterns:
+ - tolerante Profilauswertung in einer Funktion (parseProfileNameServers)
+key-files:
+ created:
+ - apps/api/prisma/migrations/20261008160000_domains_drop_default_nameservers/migration.sql
+ modified:
+ - apps/api/src/domains/autodns-parse.ts
+ - apps/api/src/domains/domain-name.ts
+ - apps/api/src/domains/domains-orders.service.ts
+ - apps/api/src/domains/domains.controller.ts
+ - apps/api/src/domains/domains-settings.service.ts
+ - apps/api/src/domains/dto/domains-order.dto.ts
+ - apps/api/src/domains/dto/domains-settings.dto.ts
+ - apps/api/prisma/schema.prisma
+ - apps/web/src/app/(portal)/modules/domains/components/RegisterTab.tsx
+ - apps/web/src/app/(portal)/modules/domains/components/SettingsTab.tsx
+ - apps/web/src/lib/domains-api.ts
+ - apps/web/src/messages/de.json
+ - apps/web/src/messages/en.json
+ - CHANGELOG.md
+ - docs/anleitung-anwender.md
+ - docs/anleitung-administration.md
+ - docs/mandantentrennung-zugriffsklassifikation.md
+decisions:
+ - Spalte DomainsConfig.defaultNameServers per Migration entfernt (Modul unveroeffentlicht, Werte wertlos)
+ - Bei Lesefehler eigener Hinweis "nicht aus AutoDNS lesen" statt "keine hinterlegt"; beide sperren die Registrierung
+ - Weniger als zwei erkannte Nameserver gelten als nicht hinterlegt; keine Kuerzung, kein Raten
+status: complete
+actuals:
+ tokens: 60000
+ tasks: 3
+ commits: 3
+plan_head_before: 95d625bd25e6713fb98a29b27bb08b8efe2ab8b0
+plan_head_after: 2176f8ecce233a5e3c6416e866f73d2a8823a37e
+completed: 2026-10-08
+---
+
+# Phase quick-261008-h3t Plan 01: Domains, Nameserver aus AutoDNS Summary
+
+Tessera liest die Standard-Nameserver der Registrierung aus dem AutoDNS-Benutzerprofil (tolerante Schluessel-Erkennung), zeigt sie nur lesend in AutoDNS-Reihenfolge, speichert sie im Entwurf und sendet sie unveraendert im einen POST /domain; die Tessera-Einstellung samt DB-Spalte ist entfernt.
+
+## Commits
+
+| Task | Commit | Beschreibung |
+| ---- | ------ | ------------ |
+| 1 (tracer) | 473738d | feat(domains): Standard-Nameserver aus dem AutoDNS-Profil lesen (h3t) |
+| 2 | 1b20b84 | feat(domains): Registrieren zeigt Nameserver aus AutoDNS nur zur Kontrolle (h3t) |
+| 3 | 2176f8e | refactor(domains): Einstellung Standard-Nameserver entfernt, Doku angepasst (h3t) |
+
+## Messungen
+
+- API-Suite: 135 Dateien, 2498 Tests gruen; Web-Suite: 132 Dateien, 1458 Tests gruen.
+- tsc (api, web) ohne Fehler; biome check auf den beruehrten Verzeichnissen sauber.
+- de/en-Schluesselparitaet gruen; kein `defaultNameServers` mehr in apps/*/src; keine firmenspezifischen Nameserver-Namen in Code, Docs, Changelog.
+- Tracer-Kette (Entwurf -> Bestaetigung -> genau ein POST /domain mit Profil-Nameservern in Profil-Reihenfolge) als Test "Nameserver aus AutoDNS (h3t)" gruen.
+- Neu gebauter Stack: Migration 20261008160000 angewendet, Spalte in der lokalen DB weg, GET settings ohne Nameserver-Feld, GET name-servers antwortet 409 notConfigured (lokal ist kein AutoDNS-Zugang hinterlegt), GET status 200.
+
+## Deviations from Plan
+
+None - plan executed exactly as written. Hinweis: ein einzelner Web-Test (domains-page, "Speichern") fiel in einem Lauf unter Last durch (Zeitueberschreitung) und war im Einzel- und Wiederholungslauf gruen; unveraendert, nicht von dieser Aenderung verursacht.
+
+## Known Stubs
+
+None.
+
+## Demo-Checkliste (vom Benutzer mit Demo-Zugang auszufuehren, nicht vom Executor)
+
+- H-1 [ASSUMED] Schluesselnamen: Der Reiter Registrieren listet die Standard-Nameserver des Demo-Benutzers in AutoDNS-Reihenfolge. Erscheint stattdessen "In AutoDNS sind keine Standard-Nameserver hinterlegt", obwohl AutoDNS Werte hat, die Warnzeile "Keine Standard-Nameserver im AutoDNS-Profil erkannt" in `docker compose logs api` lesen (sie nennt die Schluesselnamen) und `parseProfileNameServers` anpassen.
+- H-2 Der AutoDNS-Benutzer darf sein eigenes Profil lesen (kein 403; ein 403 zeigt den Hinweis "nicht aus AutoDNS lesen").
+- H-3 Eine Demo-Registrierung sendet die angezeigten Nameserver und AutoDNS akzeptiert sie ausdruecklich.
+- H-4 Live: die Liste entspricht den vier vom Benutzer genannten Werten in dieser Reihenfolge.
+- H-x ersetzt Punkt 8 (A8) der Checkliste von 261008-dts, dessen Schritt "Standard-Nameserver in den Einstellungen eintragen" entfaellt.
+
+## Browser-Schritte fuer den Orchestrator (Dunkelmodus)
+
+1. Domains -> Einstellungen: keine Karte "Standard-Nameserver" mehr.
+2. Domains -> Registrieren, Domain pruefen: entweder schreibgeschuetzte Nameserver-Liste in AutoDNS-Reihenfolge, oder (lokal ohne Zugang) Hinweis oben mit "Erneut aus AutoDNS lesen" und gesperrtem "Zusammenfassung anzeigen".
+
+## Self-Check: PASSED
+
+Commits 473738d, 1b20b84, 2176f8e liegen auf main; Migration und Parser vorhanden.