# 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
<!-- Filled in after completion -->
