# Nix Flakes Verification Checklist

This document provides a comprehensive checklist for verifying the Nix flakes integration.

## Prerequisites

- [ ] Nix installed with flakes enabled
- [ ] direnv installed (optional)
- [ ] Docker installed (for image testing)
- [ ] Cachix account created (for binary caching)

## Phase 1: Core Flake Setup

### Verify flake.nix

- [ ] `nix flake check` passes without errors
- [ ] `nix flake show` displays all packages and devShells
- [ ] `nix flake metadata` shows correct inputs

```bash
cd towerops-web
nix flake check
nix flake show
nix flake metadata
```

**Expected output:**
```
packages
├── aarch64-darwin
│   ├── dockerImage
│   ├── default: package 'towerops-0.1.0'
│   ├── towerops: package 'towerops-0.1.0'
│   └── towerops-nif: package 'towerops-nif-0.1.0'
└── x86_64-linux
    ├── dockerImage
    ├── default: package 'towerops-0.1.0'
    ├── towerops: package 'towerops-0.1.0'
    └── towerops-nif: package 'towerops-nif-0.1.0'
```

## Phase 2: C NIF Build

### Build C NIF

- [ ] `nix build .#towerops-nif` completes successfully
- [ ] Output binary exists at `result/lib/towerops_nif.so`
- [ ] Binary links against libnetsnmp

```bash
nix build .#towerops-nif
ls -lh result/lib/towerops_nif.so
ldd result/lib/towerops_nif.so | grep netsnmp
```

**Expected output:**
```
-rwxr-xr-x  1 user  group   50K Feb  7 12:00 result/lib/towerops_nif.so
libnetsnmp.so.40 => /nix/store/.../lib/libnetsnmp.so.40
```

### Verify NIF Functionality

- [ ] NIF loads without errors
- [ ] Can call MIB resolution functions

```bash
nix develop
iex -S mix
# In IEx:
ToweropsNative.load_mib_directory("priv/mibs")
# Should return: {:ok, _} or {:error, :already_initialized}
```

## Phase 3: Mix Release Build

### Build Elixir Release

- [ ] `nix build .#towerops` completes successfully
- [ ] Release binary exists at `result/bin/towerops`
- [ ] Release contains MIB files
- [ ] Release contains vendored Oban packages

```bash
nix build .#towerops
ls -lh result/bin/towerops
find result -name "*.mib" | head -5
find result -name "oban_*" -type d
```

**Expected output:**
```
-rwxr-xr-x  1 user  group  10K result/bin/towerops
result/lib/towerops-0.1.0/priv/mibs/SNMPv2-MIB.mib
result/lib/towerops-0.1.0/priv/mibs/IF-MIB.mib
...
result/lib/oban_pro-1.6.0
result/lib/oban_web-2.11.0
result/lib/oban_met-1.0.0
```

### Test Release Execution

- [ ] Release starts without errors
- [ ] RPC commands work
- [ ] MIB directory is accessible

```bash
# Test RPC
./result/bin/towerops rpc "1 + 1"
# Expected: 2

# Test MIB loading (requires database connection)
# Set up DATABASE_URL, SECRET_KEY_BASE, etc. first
export DATABASE_URL="ecto://user@localhost/towerops_dev"
export SECRET_KEY_BASE="test_secret_key_base_at_least_64_bytes_long_for_phoenix"
export CLOAK_KEY="test_cloak_key_base64_32bytes="

./result/bin/towerops eval "Application.ensure_all_started(:towerops)"
```

## Phase 4: Docker Image Build

### Build Docker Image

- [ ] `nix build .#dockerImage` completes successfully
- [ ] Image size is < 250 MB (target: 150-200 MB)
- [ ] Image loads into Docker successfully

```bash
nix build .#dockerImage
nix path-info -S .#dockerImage
docker load < result
docker images | grep towerops
```

**Expected output:**
```
/nix/store/...-docker-image-towerops-latest.tar.gz  180.5 MiB
registry.gitlab.com/towerops/towerops   latest   abc123def456   190MB
```

### Verify Image Contents

- [ ] Image contains towerops release
- [ ] Image contains net-snmp runtime
- [ ] Image contains MIB files
- [ ] Image runs as non-root user

```bash
# Check contents
docker run --rm registry.gitlab.com/towerops/towerops:latest ls -la /

# Check user
docker run --rm registry.gitlab.com/towerops/towerops:latest id
# Expected: uid=65534(nobody) gid=65534(nobody)

# Check MIB files
docker run --rm registry.gitlab.com/towerops/towerops:latest \
  find / -name "*.mib" 2>/dev/null | head -5

# Check snmptranslate
docker run --rm registry.gitlab.com/towerops/towerops:latest which snmptranslate
```

### Test Image Execution

- [ ] Image starts with healthcheck passing
- [ ] Phoenix server responds on port 4000
- [ ] RPC commands work inside container

```bash
# Start container (requires database)
docker run --rm -p 4000:4000 \
  -e DATABASE_URL="ecto://user@host.docker.internal/towerops_dev" \
  -e SECRET_KEY_BASE="test_secret_key_base_at_least_64_bytes_long" \
  -e CLOAK_KEY="test_cloak_key_base64_32bytes=" \
  -e PHX_HOST="localhost" \
  registry.gitlab.com/towerops/towerops:latest

# Test healthcheck (in another terminal)
docker ps --filter "name=towerops" --format "{{.Status}}"
# Should show "healthy" after ~30 seconds

# Test RPC
docker exec <container-id> /nix/store/.../bin/towerops rpc "1 + 1"
```

## Phase 5: Development Shell

### Enter Development Shell

- [ ] `nix develop` completes successfully
- [ ] PostgreSQL auto-starts
- [ ] Redis auto-starts
- [ ] Databases are created
- [ ] Welcome message displays

```bash
nix develop
# Should auto-start services and show welcome message
```

**Expected output:**
```
🚀 Starting development services...
📦 Initializing PostgreSQL database...
🐘 Starting PostgreSQL on port 5432...
✓ PostgreSQL started successfully
📮 Starting Redis on port 6379...
✓ Redis started successfully
✨ Development environment ready!

╔═══════════════════════════════════════════════════════════╗
║                                                           ║
║  Towerops Development Environment                        ║
║                                                           ║
╚═══════════════════════════════════════════════════════════╝
```

### Verify Services

- [ ] PostgreSQL responds to connections
- [ ] Redis responds to PING
- [ ] Databases exist
- [ ] TimescaleDB extension available (optional)

```bash
# In Nix shell
pg_isready -h localhost -p 5432
# Expected: localhost:5432 - accepting connections

redis-cli ping
# Expected: PONG

psql -U $USER -h localhost -p 5432 -l | grep towerops
# Expected: towerops_dev, towerops_test

psql -U $USER -h localhost -p 5432 -d towerops_dev -c "SELECT * FROM pg_extension WHERE extname = 'timescaledb';"
# Expected: 1 row if TimescaleDB available, 0 rows if not (ok for dev)
```

### Test Mix Commands

- [ ] `mix deps.get` works
- [ ] `mix compile` works
- [ ] `mix ecto.migrate` works
- [ ] `mix phx.server` starts
- [ ] `mix test` runs

```bash
mix deps.get
mix compile
mix ecto.migrate
mix phx.server &
sleep 5
curl http://localhost:4000
kill %1  # Stop Phoenix

mix test --only quick || mix test | head -50
```

### Verify Pre-commit Hooks

- [ ] Pre-commit hooks are installed
- [ ] `mix format` hook works
- [ ] `credo` hook works
- [ ] `nixfmt` hook works

```bash
# Make a formatting violation
echo "defmodule Foo do end" >> lib/foo.ex
git add lib/foo.ex
git commit -m "test"
# Should fail with formatting error

# Fix and retry
mix format
git add lib/foo.ex
git commit -m "test"
# Should pass or fail on other hooks

# Clean up
git reset HEAD~1
rm lib/foo.ex
```

## Phase 6: direnv Integration

### Configure direnv

- [ ] `.envrc.example` exists
- [ ] Can copy to `.envrc`
- [ ] direnv loads environment automatically

```bash
cp .envrc.example .envrc
direnv allow
cd ..
cd towerops-web
# Should auto-load environment and start services

echo $MIX_ENV
# Expected: dev

which mix
# Expected: /nix/store/.../bin/mix
```

### Verify Environment Variables

- [ ] `DATABASE_URL` is set
- [ ] `REDIS_URL` is set
- [ ] `MIX_ENV` is set to `dev`
- [ ] `SECRET_KEY_BASE` is set

```bash
echo $DATABASE_URL
echo $REDIS_URL
echo $MIX_ENV
echo $SECRET_KEY_BASE | head -c 32
```

## Phase 7: Legacy Compatibility

### Test shell.nix Compatibility

- [ ] `nix-shell` works (without flakes)
- [ ] Environment is identical to `nix develop`

```bash
nix-shell
# Should enter same environment as `nix develop`

echo $MIX_ENV
which mix
exit
```

## Phase 8: Cachix Integration

### Set Up Cachix

- [ ] Cachix account created
- [ ] Cache created: `cachix create towerops`
- [ ] Keypair generated
- [ ] Public key added to `flake.nix`

```bash
cachix create towerops
cachix generate-keypair towerops
cachix get towerops
# Copy public key to flake.nix
```

### Test Local Cachix Push

- [ ] Can push builds to cache
- [ ] Can pull builds from cache

```bash
# Push build to cache
nix build .#dockerImage
nix path-info --json .#dockerImage | jq -r '.[].path' | cachix push towerops

# Verify push
cachix info towerops
# Should show recent push

# Clean local store
nix-collect-garbage -d

# Rebuild (should pull from cache)
time nix build .#dockerImage
# Should be much faster (seconds vs minutes)
```

### Configure GitLab CI

- [ ] `CACHIX_AUTH_TOKEN` added to GitLab variables
- [ ] `.gitlab-ci.yml.nix` updated with correct public key
- [ ] Ready to activate Nix CI

```bash
# Get auth token
cachix authtoken
# Add to GitLab: Settings → CI/CD → Variables

# Verify .gitlab-ci.yml.nix has correct key
grep "towerops.cachix.org-1:" .gitlab-ci.yml.nix
```

## Phase 9: Documentation

### Verify Documentation

- [ ] `docs/nix.md` exists and is comprehensive
- [ ] `docs/README-nix-section.md` created for README update
- [ ] `docs/CLAUDE-nix-section.md` created for CLAUDE.md update
- [ ] All code examples in docs are accurate

```bash
ls -lh docs/nix.md docs/README-nix-section.md docs/CLAUDE-nix-section.md

# Test commands from docs
# (Run through "Quick Start" section)
```

## Performance Benchmarks

### Measure Build Times

- [ ] C NIF build time
- [ ] Elixir release build time
- [ ] Docker image build time
- [ ] Total clean build time

```bash
# Clean builds
nix-collect-garbage -d

time nix build .#towerops-nif
# Target: < 1 minute

time nix build .#towerops
# Target: < 10 minutes (first build)

time nix build .#dockerImage
# Target: < 15 minutes (first build)

# Cached rebuilds (after changing one Elixir file)
echo "# comment" >> lib/towerops_web/router.ex
time nix build .#towerops --rebuild
# Target: < 5 minutes
```

### Measure Image Size

- [ ] Docker image size < 250 MB
- [ ] Compare to previous Debian-based image

```bash
nix path-info -S .#dockerImage
docker images | grep towerops

# Compare to old image (if available)
# Target: ~50% reduction
```

## Production Deployment Test

### Deploy to Staging/Production

- [ ] Build image with Nix
- [ ] Push to GitLab registry
- [ ] Deploy to Kubernetes
- [ ] Health checks pass
- [ ] Application functionality verified

```bash
# Build and tag
nix build .#dockerImage
docker load < result
docker tag registry.gitlab.com/towerops/towerops:latest \
  registry.gitlab.com/towerops/towerops:nix-test

# Push to registry
docker push registry.gitlab.com/towerops/towerops:nix-test

# Deploy to staging (adjust namespace/deployment as needed)
kubectl set image deployment/towerops \
  towerops=registry.gitlab.com/towerops/towerops:nix-test \
  -n towerops-staging

# Verify deployment
kubectl get pods -n towerops-staging
kubectl logs -n towerops-staging deployment/towerops --tail=50

# Check health
kubectl exec -n towerops-staging deployment/towerops -- \
  /nix/store/.../bin/towerops rpc "1 + 1"
```

## Success Criteria Summary

All items below must pass:

- [x] `nix flake check` passes
- [ ] C NIF builds and links correctly
- [ ] Mix release builds with assets and MIB files
- [ ] Docker image builds and is < 250 MB
- [ ] Development shell starts services automatically
- [ ] direnv integration works seamlessly
- [ ] Cachix push/pull works
- [ ] Documentation is comprehensive
- [ ] Production deployment succeeds

## Issues Tracker

Document any issues encountered during verification:

| Phase | Issue | Resolution | Status |
|-------|-------|------------|--------|
| Example | Error XYZ | Fixed by ABC | Resolved |
|  |  |  |  |

## Final Sign-Off

- [ ] All verification steps completed
- [ ] All issues resolved or documented
- [ ] Ready for production use
- [ ] Team trained on Nix workflows

**Verified by:** _______________
**Date:** _______________
**Nix version:** _______________
**Platform:** _______________
