# Phase 3: DNS Lifecycle Hooks **Status:** ⬜ Not Started **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** backend ## Objective Hook DNS record management into the deployer and standalone proxy manager so that DNS records are automatically created/updated/deleted in sync with proxy consumers. ## Tasks - [ ] Task 1: Create `dns_records` table for tracking managed records - Columns: id, fqdn, provider_record_id, consumer_type (instance/standalone), consumer_id, created_at, updated_at - Store queries: CreateDNSRecord, DeleteDNSRecord, GetDNSRecordByFQDN, ListDNSRecords, GetDNSRecordsByConsumer - [ ] Task 2: Add DNS provider to `Deployer` struct - Accept `dns.Provider` in constructor (can be nil for wildcard mode) - Helper: `ensureDNS(ctx, fqdn, deployID)` — calls provider.EnsureRecord + saves to dns_records - Helper: `removeDNS(ctx, fqdn, deployID)` — calls provider.DeleteRecord + removes from dns_records - [ ] Task 3: Hook into deployer — instance creation - After `configureProxy` succeeds in `deployer.go` and `bluegreen.go` → call `ensureDNS` - FQDN = `subdomain + "." + settings.Domain` - [ ] Task 4: Hook into deployer — instance removal - In `removeInstance` after NPM proxy deletion → call `removeDNS` - In `rollback` after NPM proxy deletion → call `removeDNS` - [ ] Task 5: Hook into standalone proxy manager - `CreateProxy` → after NPM host created, call `ensureDNS` - `UpdateProxy` → if domain changed, `removeDNS(old)` + `ensureDNS(new)` - `DeleteProxy` → call `removeDNS` - [ ] Task 6: Wire DNS provider into main.go - Read settings on startup, create provider if non-wildcard - Pass provider to Deployer and proxy Manager constructors - Handle provider being nil (wildcard mode = no DNS ops) - [ ] Task 7: Add `DNSRecord` model to `internal/store/models.go` ## Files to Modify/Create - `internal/store/models.go` — add DNSRecord struct - `internal/store/store.go` — add dns_records table migration - `internal/store/dns_records.go` — CRUD queries - `internal/deployer/deployer.go` — add DNS hooks - `internal/deployer/bluegreen.go` — add DNS hooks - `internal/deployer/rollback.go` — add DNS cleanup - `internal/proxy/manager.go` — add DNS hooks - `cmd/server/main.go` — wire DNS provider ## Acceptance Criteria - DNS records created when proxy consumers are created (if non-wildcard mode) - DNS records deleted when proxy consumers are removed - DNS records updated when standalone proxy domain changes - All DNS operations are best-effort (log warning on failure, don't block) - dns_records table tracks all managed records - Wildcard mode (default) skips all DNS operations ## Notes - DNS operations must be wrapped in error handling that logs but doesn't fail the deploy - The dns_records table is the local source of truth for reconciliation (Phase 6) - Provider can be nil — all hooks must check for nil before calling ## Review Checklist - [ ] All tasks completed - [ ] Code follows project conventions - [ ] No unintended side effects - [ ] Build passes - [ ] Tests pass (new + existing) ## Handoff to Next Phase